📄 adeos-ipipe-2.6.14-ppc64-1.1-00.patch
字号:
++ if (handler == IPIPE_SAME_HANDLER) {+ handler = ipd->irqs[irq].handler;+ cookie = ipd->irqs[irq].cookie;++ if (handler == NULL) {+ err = -EINVAL;+ goto unlock_and_exit;+ }+ } else if ((modemask & IPIPE_EXCLUSIVE_MASK) != 0 &&+ ipd->irqs[irq].handler != NULL) {+ err = -EBUSY;+ goto unlock_and_exit;+ }++ if ((modemask & (IPIPE_SHARED_MASK | IPIPE_PASS_MASK)) ==+ IPIPE_SHARED_MASK) {+ err = -EINVAL;+ goto unlock_and_exit;+ }++ if ((modemask & IPIPE_STICKY_MASK) != 0)+ modemask |= IPIPE_HANDLE_MASK;+ } else+ modemask &=+ ~(IPIPE_HANDLE_MASK | IPIPE_STICKY_MASK |+ IPIPE_SHARED_MASK);++ if (acknowledge == NULL) {+ if ((modemask & IPIPE_SHARED_MASK) == 0)+ /* Acknowledge handler unspecified -- this is ok in+ non-shared management mode, but we will force the use+ of the Linux-defined handler instead. */+ acknowledge = ipipe_root_domain->irqs[irq].acknowledge;+ else {+ /* A valid acknowledge handler to be called in shared mode+ is required when declaring a shared IRQ. */+ err = -EINVAL;+ goto unlock_and_exit;+ }+ }++ ipd->irqs[irq].handler = handler;+ ipd->irqs[irq].cookie = cookie;+ ipd->irqs[irq].acknowledge = acknowledge;+ ipd->irqs[irq].control = modemask;++ if (irq < NR_IRQS &&+ handler != NULL &&+ !ipipe_virtual_irq_p(irq) && (modemask & IPIPE_ENABLE_MASK) != 0) {+ if (ipd != ipipe_current_domain) {+ /* IRQ enable/disable state is domain-sensitive, so we may+ not change it for another domain. What is allowed+ however is forcing some domain to handle an interrupt+ source, by passing the proper 'ipd' descriptor which+ thus may be different from ipipe_current_domain. */+ err = -EPERM;+ goto unlock_and_exit;+ }++ __ipipe_enable_irq(irq);+ }++ err = 0;++ unlock_and_exit:++ spin_unlock_irqrestore_hw(&__ipipe_pipelock, flags);++ return err;+}++/* ipipe_control_irq() -- Change modes of a pipelined interrupt for+ * the current domain. */++int ipipe_control_irq(unsigned irq, unsigned clrmask, unsigned setmask)+{+ struct ipipe_domain *ipd;+ unsigned long flags;++ if (irq >= IPIPE_NR_IRQS)+ return -EINVAL;++ ipd = ipipe_current_domain;++ if (ipd->irqs[irq].control & IPIPE_SYSTEM_MASK)+ return -EPERM;++ if (((setmask | clrmask) & IPIPE_SHARED_MASK) != 0)+ return -EINVAL;++ if (ipd->irqs[irq].handler == NULL)+ setmask &= ~(IPIPE_HANDLE_MASK | IPIPE_STICKY_MASK);++ if ((setmask & IPIPE_STICKY_MASK) != 0)+ setmask |= IPIPE_HANDLE_MASK;++ if ((clrmask & (IPIPE_HANDLE_MASK | IPIPE_STICKY_MASK)) != 0) /* If one goes, both go. */+ clrmask |= (IPIPE_HANDLE_MASK | IPIPE_STICKY_MASK);++ spin_lock_irqsave_hw(&__ipipe_pipelock, flags);++ ipd->irqs[irq].control &= ~clrmask;+ ipd->irqs[irq].control |= setmask;++ if ((setmask & IPIPE_ENABLE_MASK) != 0)+ __ipipe_enable_irq(irq);+ else if ((clrmask & IPIPE_ENABLE_MASK) != 0)+ __ipipe_disable_irq(irq);++ spin_unlock_irqrestore_hw(&__ipipe_pipelock, flags);++ return 0;+}++/* __ipipe_dispatch_event() -- Low-level event dispatcher. */++int fastcall __ipipe_dispatch_event (unsigned event, void *data)+{+ struct ipipe_domain *start_domain, *this_domain, *next_domain;+ struct list_head *pos, *npos;+ unsigned long flags;+ ipipe_declare_cpuid;+ int propagate = 1;++ ipipe_lock_cpu(flags);++ start_domain = this_domain = ipipe_percpu_domain[cpuid];++ list_for_each_safe(pos,npos,&__ipipe_pipeline) {++ next_domain = list_entry(pos,struct ipipe_domain,p_link);++ /*+ * Note: Domain migration may occur while running+ * event or interrupt handlers, in which case the+ * current register set is going to be recycled for a+ * different domain than the initiating one. We do+ * care for that, always tracking the current domain+ * descriptor upon return from those handlers.+ */+ if (next_domain->evhand[event] != NULL) {+ ipipe_percpu_domain[cpuid] = next_domain;+ ipipe_unlock_cpu(flags);+ propagate = !next_domain->evhand[event](event,start_domain,data);+ ipipe_lock_cpu(flags);+ if (ipipe_percpu_domain[cpuid] != next_domain)+ this_domain = ipipe_percpu_domain[cpuid];+ }++ if (next_domain != ipipe_root_domain && /* NEVER sync the root stage here. */+ next_domain->cpudata[cpuid].irq_pending_hi != 0 &&+ !test_bit(IPIPE_STALL_FLAG,&next_domain->cpudata[cpuid].status)) {+ ipipe_percpu_domain[cpuid] = next_domain;+ __ipipe_sync_stage(IPIPE_IRQMASK_ANY);+ ipipe_load_cpuid();+ if (ipipe_percpu_domain[cpuid] != next_domain)+ this_domain = ipipe_percpu_domain[cpuid];+ }++ ipipe_percpu_domain[cpuid] = this_domain;++ if (next_domain == this_domain || !propagate)+ break;+ }++ ipipe_unlock_cpu(flags);++ return !propagate;+}++#ifdef CONFIG_PROC_FS++#include <linux/proc_fs.h>++struct proc_dir_entry *ipipe_proc_root;++static int __ipipe_version_info_proc(char *page,+ char **start,+ off_t off, int count, int *eof, void *data)+{+ int len = sprintf(page, "%s\n", IPIPE_VERSION_STRING);++ len -= off;++ if (len <= off + count)+ *eof = 1;++ *start = page + off;++ if(len > count)+ len = count;++ if(len < 0)+ len = 0;++ return len;+}++static int __ipipe_common_info_proc(char *page,+ char **start,+ off_t off, int count, int *eof, void *data)+{+ struct ipipe_domain *ipd = (struct ipipe_domain *)data;+ unsigned long ctlbits;+ unsigned irq, _irq;+ char *p = page;+ int len;++ spin_lock(&__ipipe_pipelock);++ p += sprintf(p, "Priority=%d, Id=0x%.8x\n",+ ipd->priority, ipd->domid);+ irq = 0;++ while (irq < IPIPE_NR_IRQS) {+ ctlbits =+ (ipd->irqs[irq].+ control & (IPIPE_HANDLE_MASK | IPIPE_PASS_MASK |+ IPIPE_STICKY_MASK));+ if (irq >= IPIPE_NR_XIRQS && !ipipe_virtual_irq_p(irq)) {+ /*+ * There might be a hole between the last external+ * IRQ and the first virtual one; skip it.+ */+ irq++;+ continue;+ }++ if (ipipe_virtual_irq_p(irq)+ && !test_bit(irq - IPIPE_VIRQ_BASE,+ &__ipipe_virtual_irq_map)) {+ /* Non-allocated virtual IRQ; skip it. */+ irq++;+ continue;+ }++ /*+ * Attempt to group consecutive IRQ numbers having the+ * same virtualization settings in a single line.+ */++ _irq = irq;++ while (++_irq < IPIPE_NR_IRQS) {+ if (ipipe_virtual_irq_p(_irq) !=+ ipipe_virtual_irq_p(irq)+ || (ipipe_virtual_irq_p(_irq)+ && !test_bit(_irq - IPIPE_VIRQ_BASE,+ &__ipipe_virtual_irq_map))+ || ctlbits != (ipd->irqs[_irq].+ control & (IPIPE_HANDLE_MASK |+ IPIPE_PASS_MASK |+ IPIPE_STICKY_MASK)))+ break;+ }++ if (_irq == irq + 1)+ p += sprintf(p, "irq%u: ", irq);+ else+ p += sprintf(p, "irq%u-%u: ", irq, _irq - 1);++ /*+ * Statuses are as follows:+ * o "accepted" means handled _and_ passed down the pipeline.+ * o "grabbed" means handled, but the interrupt might be+ * terminated _or_ passed down the pipeline depending on+ * what the domain handler asks for to the I-pipe.+ * o "passed" means unhandled by the domain but passed+ * down the pipeline.+ * o "discarded" means unhandled and _not_ passed down the+ * pipeline. The interrupt merely disappears from the+ * current domain down to the end of the pipeline.+ */+ if (ctlbits & IPIPE_HANDLE_MASK) {+ if (ctlbits & IPIPE_PASS_MASK)+ p += sprintf(p, "accepted");+ else+ p += sprintf(p, "grabbed");+ } else if (ctlbits & IPIPE_PASS_MASK)+ p += sprintf(p, "passed");+ else+ p += sprintf(p, "discarded");++ if (ctlbits & IPIPE_STICKY_MASK)+ p += sprintf(p, ", sticky");++ if (ipipe_virtual_irq_p(irq))+ p += sprintf(p, ", virtual");++ p += sprintf(p, "\n");++ irq = _irq;+ }++ spin_unlock(&__ipipe_pipelock);++ len = p - page;++ if (len <= off + count)+ *eof = 1;++ *start = page + off;++ len -= off;++ if (len > count)+ len = count;++ if (len < 0)+ len = 0;++ return len;+}++#ifdef CONFIG_IPIPE_STATS++static int __ipipe_stat_info_proc(char *page,+ char **start,+ off_t off, int count, int *eof, void *data)+{+ struct ipipe_domain *ipd = (struct ipipe_domain *)data;+ int len = 0, cpu, irq;+ char *p = page;++ p += sprintf(p,"> STALL TIME:\n");++ for_each_online_cpu(cpu) {+ unsigned long eip = ipd->stats[cpu].max_stall_eip;+ char namebuf[KSYM_NAME_LEN+1];+ unsigned long offset, size, t;+ const char *name;+ char *modname;++ name = kallsyms_lookup(eip, &size, &offset, &modname, namebuf);+ t = ipipe_tsc2ns(ipd->stats[cpu].max_stall_time);++ if (name) {+ if (modname)+ p += sprintf(p,"CPU%d %12lu (%s+%#lx [%s])\n",+ cpu,t,name,offset,modname);+ else+ p += sprintf(p,"CPU%d %12lu (%s+%#lx)\n",+ cpu,t,name,offset);+ }+ else+ p += sprintf(p,"CPU%d %12lu (%lx)\n",+ cpu,t,eip);+ }++ p += sprintf(p,"> PROPAGATION TIME:\nIRQ");++ for_each_online_cpu(cpu) {+ p += sprintf(p," CPU%d",cpu);+ }++ for (irq = 0; irq < IPIPE_NR_IRQS; irq++) {++ unsigned long long t = 0;++ for_each_online_cpu(cpu) {+ t += ipd->stats[cpu].irq_stats[irq].max_delivery_time;+ }++ if (!t)+ continue;++ p += sprintf(p,"\n%3d:",irq);++ for_each_online_cpu(cpu) {+ p += sprintf(p,"%13lu",+ ipipe_tsc2ns(ipd->stats[cpu].irq_stats[irq].max_delivery_time));+ }+ }++ p += sprintf(p,"\n");++ len = p - page - off;+ if (len <= off + count) *eof = 1;+ *start = page + off;+ if (len > count) len = count;+ if (len < 0) len = 0;++ return len;+}++#endif /* CONFIG_IPIPE_STATS */++void __ipipe_add_domain_proc(struct ipipe_domain *ipd)+{++ create_proc_read_entry(ipd->name,0444,ipipe_proc_root,&__ipipe_common_info_proc,ipd);+#ifdef CONFIG_IPIPE_STATS+ {+ char name[64];+ snprintf(name,sizeof(name),"%s_stats",ipd->name);+ create_proc_read_entry(name,0444,ipipe_proc_root,&__ipipe_stat_info_proc,ipd);+ }+#endif /* CONFIG_IPIPE_STATS */+}++void __ipipe_remove_domain_proc(struct ipipe_domain *ipd)+{+ remove_proc_entry(ipd->name,ipipe_proc_root);+#ifdef CONFIG_IPIPE_STATS+ {+ char name[64];+ snprintf(name,sizeof(name),"%s_stats",ipd->name);+ remove_proc_entry(name,ipipe_proc_root);+ }+#endif /* CONFIG_IPIPE_STATS */+}++void ipipe_init_proc(void)+{+ ipipe_proc_root = create_proc_entry("ipipe",S_IFDIR, 0);+ create_proc_read_entry("version",0444,ipipe_proc_root,&__ipipe_version_info_proc,NULL);+ __ipipe_init_trace_proc();+ __ipipe_add_domain_proc(ipipe_root_domain);+}++#endif /* CONFIG_PROC_FS */++EXPORT_SYMBOL(ipipe_virtualize_irq);+EXPORT_SYMBOL(ipipe_control_irq);+EXPORT_SYMBOL(ipipe_suspend_domain);+EXPORT_SYMBOL(ipipe_alloc_virq);+EXPORT_SYMBOL(ipipe_unstall_pipeline_from);+EXPORT_SYMBOL(ipipe_percpu_domain);+EXPORT_SYMBOL(ipipe_root_domain);+EXPORT_SYMBOL(__ipipe_unstall_root);+EXPORT_SYMBOL(__ipipe_stall_root);+EXPORT_SYMBOL(__ipipe_restore_root);+EXPORT_SYMBOL(__ipipe_test_and_stall_root);+EXPORT_SYMBOL(__ipipe_test_root);+EXPORT_SYMBOL(__ipipe_dispatch_event);+EXPORT_SYMBOL(__ipipe_pipeline);+EXPORT_SYMBOL(__ipipe_pipelock);+EXPORT_SYMBOL(__ipipe_virtual_irq_map);--- 2.6.14/kernel/ipipe/generic.c 1970-01-01 01:00:00.000000000 +0100+++ 2.6.14-ipipe/kernel/ipipe/generic.c 2006-01-06 09:27:24.000000000 +0100@@ -0,0 +1,397 @@+/* -*- linux-c -*-+ * linux/kernel/ipipe/generic.c+ *+ * Copyright (C) 2002-2005 Philippe Gerum.+ *+ * 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, Inc., 675 Mass Ave, Cambridge MA 02139,+ * USA; 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.+ *+ * Architecture-independent I-PIPE services.+ */++#include <linux/version.h>+#include <linux/module.h>+#include <linux/init.h>+#include <linux/kernel.h>+#include <linux/sched.h>+#ifdef CONFIG_PROC_FS+#include <linux/proc_fs.h>+#endif /* CONFIG_PROC_FS */++MODULE_DESCRIPTION("I-pipe");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -