* [RFC PATCH 2/4] powerpc 2.6.16-rt17: to boot on powerpc w/ RT
From: Tsutomu OWA @ 2006-08-11 2:02 UTC (permalink / raw)
To: linux-kernel; +Cc: linuxppc-dev, mingo, tglx
To boot on powermac and cell.
---
with PREEMPT_RT
BUG: using smp_processor_id() in preemptible [00000000] code: init/1
caller is .hpte_update+0x4c/0x250
Call Trace:
[C000000001467850] [C00000000000F250] .show_stack+0x68/0x1b4
(unreliable)
[C000000001467900] [C00000000014C4A4] .debug_smp_processor_id+0xc4/0xf4
[C000000001467990] [C00000000002BEC0] .hpte_update+0x4c/0x250
[C000000001467A40] [C00000000008C670] .do_wp_page+0x474/0x618
[C000000001467B10] [C00000000008DC30] .__handle_mm_fault+0xd50/0xe68
[C000000001467C20] [C000000000029EFC] .do_page_fault+0x48c/0x674
[C000000001467E30] [C000000000004760] .handle_page_fault+0x20/0x54
o to enable drivers.
powermac/low_i2c.c:
struct semaphore -> struct compat_semaphore
spinlock_t -> raw_spinlock_t
drivers/net/sungem.c: transmit_tx_frame(). try_spinlock_irqsave()
make spinlock_t to raw_spinlock_t for mpic and native_tlbie_lock.
make struct semaphore to struct compat_semaphore for kw2_i2c.
* to boot on cell
o port systemsim bogus disk and console. (not included in this patch)
with PREEMPT_RT
BUG: swapper:0 task might have lost a preemption check!
Call Trace:
[C0000000002FFC40] [C00000000000F250] .show_stack+0x68/0x1b4
(unreliable)
[C0000000002FFCF0] [C0000000000425F8]
.preempt_enable_no_resched+0x68/0x80
[C0000000002FFD70] [C000000000032EC0] .cbe_idle+0x168/0x184
[C0000000002FFE00] [C000000000018DD0] .cpu_idle+0x4c/0x60
[C0000000002FFE70] [C000000000009290] .rest_init+0x60/0x78
[C0000000002FFEF0] [C0000000002CE890] .start_kernel+0x310/0x330
[C0000000002FFF90] [C000000000008574] .start_here_common+0x88/0x114
--
BUG: using smp_processor_id() in preemptible [00000000] code: init/1
caller is .hpte_update+0x4c/0x250
Call Trace:
[C000000001467850] [C00000000000F250] .show_stack+0x68/0x1b4
(unreliable)
[C000000001467900] [C00000000014C4A4] .debug_smp_processor_id+0xc4/0xf4
[C000000001467990] [C00000000002BEC0] .hpte_update+0x4c/0x250
[C000000001467A40] [C00000000008C670] .do_wp_page+0x474/0x618
[C000000001467B10] [C00000000008DC30] .__handle_mm_fault+0xd50/0xe68
[C000000001467C20] [C000000000029EFC] .do_page_fault+0x48c/0x674
[C000000001467E30] [C000000000004760] .handle_page_fault+0x20/0x54
-- owa
diff -rup -x CVS 2.6.16-rt17/arch/powerpc/mm/hash_native_64.c rt-powerpc/arch/powerpc/mm/hash_native_64.c
--- 2.6.16-rt17/arch/powerpc/mm/hash_native_64.c 2006-03-20 14:53:29.000000000 +0900
+++ rt-powerpc/arch/powerpc/mm/hash_native_64.c 2006-07-12 14:38:24.000000000 +0900
@@ -35,7 +35,10 @@
#define HPTE_LOCK_BIT 3
-static DEFINE_SPINLOCK(native_tlbie_lock);
+/*
+ * to avoid "BUG: scheduling while atomic at native_flush_hash_range.
+ */
+static DEFINE_RAW_SPINLOCK(native_tlbie_lock);
static inline void __tlbie(unsigned long va, unsigned int psize)
{
diff -rup -x CVS 2.6.16-rt17/arch/powerpc/mm/tlb_64.c rt-powerpc/arch/powerpc/mm/tlb_64.c
--- 2.6.16-rt17/arch/powerpc/mm/tlb_64.c 2006-04-26 18:24:28.000000000 +0900
+++ rt-powerpc/arch/powerpc/mm/tlb_64.c 2006-07-12 13:47:32.000000000 +0900
@@ -95,9 +95,15 @@ static void pte_free_submit(struct pte_f
void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf)
{
+#ifndef CONFIG_PREEMPT_RT
/* This is safe since tlb_gather_mmu has disabled preemption */
cpumask_t local_cpumask = cpumask_of_cpu(smp_processor_id());
struct pte_freelist_batch **batchp = &__get_cpu_var(pte_freelist_cur);
+#else
+ cpumask_t local_cpumask = cpumask_of_cpu(raw_smp_processor_id());
+ struct pte_freelist_batch **batchp = &get_cpu_var(pte_freelist_cur);
+ put_cpu_var(pte_freelist_cur);
+#endif /* !CONFIG_PREEMPT_RT */
if (atomic_read(&tlb->mm->mm_users) < 2 ||
cpus_equal(tlb->mm->cpu_vm_mask, local_cpumask)) {
diff -rup -x CVS 2.6.16-rt17/arch/powerpc/platforms/cell/pervasive.c rt-powerpc/arch/powerpc/platforms/cell/pervasive.c
--- 2.6.16-rt17/arch/powerpc/platforms/cell/pervasive.c 2006-03-20 14:53:29.000000000 +0900
+++ rt-powerpc/arch/powerpc/platforms/cell/pervasive.c 2006-07-12 13:48:09.000000000 +0900
@@ -136,8 +136,8 @@ static void cbe_idle(void)
*/
ppc64_runlatch_on();
- preempt_enable_no_resched();
- schedule();
+ __preempt_enable_no_resched();
+ __schedule();
preempt_disable();
}
}
diff -rup -x CVS 2.6.16-rt17/arch/powerpc/platforms/powermac/low_i2c.c rt-powerpc/arch/powerpc/platforms/powermac/low_i2c.c
--- 2.6.16-rt17/arch/powerpc/platforms/powermac/low_i2c.c 2006-03-20 14:53:29.000000000 +0900
+++ rt-powerpc/arch/powerpc/platforms/powermac/low_i2c.c 2006-07-12 13:49:09.000000000 +0900
@@ -85,7 +85,7 @@ struct pmac_i2c_bus
void *hostdata;
int channel; /* some hosts have multiple */
int mode; /* current mode */
- struct semaphore sem;
+ struct compat_semaphore sem;
int opened;
int polled; /* open mode */
struct platform_device *platform_dev;
@@ -105,7 +105,7 @@ static LIST_HEAD(pmac_i2c_busses);
struct pmac_i2c_host_kw
{
- struct semaphore mutex; /* Access mutex for use by
+ struct compat_semaphore mutex; /* Access mutex for use by
* i2c-keywest */
void __iomem *base; /* register base address */
int bsteps; /* register stepping */
@@ -119,6 +119,9 @@ struct pmac_i2c_host_kw
int result;
struct completion complete;
spinlock_t lock;
+ /* "BUG: scheduling while at atomic" at del_timer() called
+ * from kw_i2c_irq() if raw_spinlock_t.
+ */
struct timer_list timeout_timer;
};
diff -rup -x CVS 2.6.16-rt17/arch/powerpc/sysdev/mpic.c rt-powerpc/arch/powerpc/sysdev/mpic.c
--- 2.6.16-rt17/arch/powerpc/sysdev/mpic.c 2006-03-20 14:53:29.000000000 +0900
+++ rt-powerpc/arch/powerpc/sysdev/mpic.c 2006-07-11 16:19:06.000000000 +0900
@@ -45,7 +45,7 @@
static struct mpic *mpics;
static struct mpic *mpic_primary;
-static DEFINE_SPINLOCK(mpic_lock);
+static DEFINE_RAW_SPINLOCK(mpic_lock);
#ifdef CONFIG_PPC32 /* XXX for now */
#ifdef CONFIG_IRQ_ALL_CPUS
@@ -1009,13 +1009,13 @@ void mpic_request_ipis(void)
printk("requesting IPIs ... \n");
/* IPIs are marked SA_INTERRUPT as they must run with irqs disabled */
- request_irq(mpic->ipi_offset+0, mpic_ipi_action, SA_INTERRUPT,
+ request_irq(mpic->ipi_offset+0, mpic_ipi_action, SA_INTERRUPT | SA_NODELAY,
"IPI0 (call function)", mpic);
- request_irq(mpic->ipi_offset+1, mpic_ipi_action, SA_INTERRUPT,
+ request_irq(mpic->ipi_offset+1, mpic_ipi_action, SA_INTERRUPT | SA_NODELAY,
"IPI1 (reschedule)", mpic);
- request_irq(mpic->ipi_offset+2, mpic_ipi_action, SA_INTERRUPT,
+ request_irq(mpic->ipi_offset+2, mpic_ipi_action, SA_INTERRUPT | SA_NODELAY,
"IPI2 (unused)", mpic);
- request_irq(mpic->ipi_offset+3, mpic_ipi_action, SA_INTERRUPT,
+ request_irq(mpic->ipi_offset+3, mpic_ipi_action, SA_INTERRUPT | SA_NODELAY,
"IPI3 (debugger break)", mpic);
printk("IPIs requested... \n");
diff -rup -x CVS 2.6.16-rt17/drivers/ide/ide-io.c rt-powerpc/drivers/ide/ide-io.c
--- 2.6.16-rt17/drivers/ide/ide-io.c 2006-04-26 18:24:28.000000000 +0900
+++ rt-powerpc/drivers/ide/ide-io.c 2006-07-12 13:50:47.000000000 +0900
@@ -1560,8 +1560,10 @@ irqreturn_t ide_intr (int irq, void *dev
del_timer(&hwgroup->timer);
spin_unlock(&ide_lock);
+#if !defined(CONFIG_PREEMPT_HARDIRQS) || !defined(CONFIG_PPC_PMAC64)
if (drive->unmask)
local_irq_enable_nort();
+#endif /* !(CONFIG_PREEMPT_HARDIRQS && CONFIG_PPC_PMAC64) */
/* service this interrupt, may set handler for next interrupt */
startstop = handler(drive);
spin_lock_irq(&ide_lock);
diff -rup -x CVS 2.6.16-rt17/drivers/ide/ide-probe.c rt-powerpc/drivers/ide/ide-probe.c
--- 2.6.16-rt17/drivers/ide/ide-probe.c 2006-04-26 18:24:28.000000000 +0900
+++ rt-powerpc/drivers/ide/ide-probe.c 2006-07-12 14:07:23.000000000 +0900
@@ -51,6 +51,7 @@
#include <linux/spinlock.h>
#include <linux/kmod.h>
#include <linux/pci.h>
+#include <linux/irq.h>
#include <asm/byteorder.h>
#include <asm/irq.h>
@@ -1088,6 +1089,10 @@ static int init_irq (ide_hwif_t *hwif)
sa = SA_SHIRQ;
#endif /* __mc68000__ || CONFIG_APUS */
+#if defined(CONFIG_PREEMPT_HARDIRQS) && defined(CONFIG_PPC_PMAC64)
+ sa |= SA_NODELAY | SA_INTERRUPT;
+#endif /* (CONFIG_PREEMPT_HARDIRQS && CONFIG_PPC_PMAC64) */
+
if (IDE_CHIPSET_IS_PCI(hwif->chipset)) {
sa = SA_SHIRQ;
#ifndef CONFIG_IDEPCI_SHARE_IRQ
diff -rup -x CVS 2.6.16-rt17/drivers/net/sungem.c rt-powerpc/drivers/net/sungem.c
--- 2.6.16-rt17/drivers/net/sungem.c 2006-03-20 14:53:29.000000000 +0900
+++ rt-powerpc/drivers/net/sungem.c 2006-07-11 17:07:43.000000000 +0900
@@ -1036,10 +1036,8 @@ static int gem_start_xmit(struct sk_buff
(csum_stuff_off << 21));
}
- local_irq_save(flags);
- if (!spin_trylock(&gp->tx_lock)) {
+ if (!spin_trylock_irqsave(&gp->tx_lock, flags)) {
/* Tell upper layer to requeue */
- local_irq_restore(flags);
return NETDEV_TX_LOCKED;
}
/* We raced with gem_do_stop() */
diff -rup -x CVS 2.6.16-rt17/include/asm-powerpc/mpic.h rt-powerpc/include/asm-powerpc/mpic.h
--- 2.6.16-rt17/include/asm-powerpc/mpic.h 2006-03-20 14:53:29.000000000 +0900
+++ rt-powerpc/include/asm-powerpc/mpic.h 2006-05-19 20:48:49.000000000 +0900
@@ -160,7 +160,7 @@ struct mpic
#ifdef CONFIG_MPIC_BROKEN_U3
/* The fixup table */
struct mpic_irq_fixup *fixups;
- spinlock_t fixup_lock;
+ raw_spinlock_t fixup_lock;
#endif
/* The various ioremap'ed bases */
diff -rup -x CVS 2.6.16-rt17/kernel/latency.c rt-powerpc/kernel/latency.c
--- 2.6.16-rt17/kernel/latency.c 2006-04-26 18:24:29.000000000 +0900
+++ rt-powerpc/kernel/latency.c 2006-07-12 13:57:31.000000000 +0900
@@ -1787,7 +1787,12 @@ void notrace add_preempt_count(unsigned
#endif
preempt_count() += val;
+
#ifdef CONFIG_PREEMPT_TRACE
+#if 1 /* FIXME: somehow current is NULL. why? */
+ if (!current)
+ return;
+#endif
^ permalink raw reply
* [RFC PATCH 1/4] powerpc 2.6.16-rt17: to build on powerpc w/ RT
From: Tsutomu OWA @ 2006-08-11 2:01 UTC (permalink / raw)
To: linux-kernel; +Cc: linuxppc-dev, mingo, tglx
To fix following compile errors for powermac and cell.
---
with PREEMPT_NONE
o arch/powerpc/kernel/head_64.S
include/asm-generic/bug.h: Assembler messages:
include/asm-generic/bug.h:19: Error: Unrecognized opcode: `extern'
o missing percpu related macros
arch/powerpc/mm/mem.c
In file included from include/asm/tlb.h:53,
from arch/powerpc/mm/mem.c:45:
include/asm-generic/tlb.h:50: error: parse error before "mmu_gathers"
include/asm-generic/tlb.h:50: warning: type defaults to `int' in
declaration of `DECLARE_PER_CPU_LOCKED'
etc.
o kernel/time/clockevents.c:82: error: conflicting types for
'timer_interrupt'
include/asm/hw_irq.h:14: error: previous declaration of
'timer_interrupt' was here
kernel/time/clockevents.c:82: error: conflicting types for
'timer_interrupt'
include/asm/hw_irq.h:14: error: previous declaration of
'timer_interrupt' was here
o kernel/built-in.o: In function `do_gettimeofday':
: multiple definition of `do_gettimeofday'
arch/powerpc/kernel/built-in.o:: first defined here
kernel/built-in.o: In function `.do_gettimeofday':
: multiple definition of `.do_gettimeofday'
arch/powerpc/kernel/built-in.o:: first defined here
/usr/local/sti/SDK0.29/bin/pu64-ld: Warning: size of symbol
`.do_gettimeofday' changed from 120 in arch/powerpc/kernel/built-in.o
to 372 in kernel/built-in.o
arch/powerpc/kernel/built-in.o: In function `.do_gettimeofday':
o arch/powerpc/kernel/built-in.o: In function `.do_gettimeofday':
: undefined reference to `.SCALE_XSEC'
with PREEMPT_RT
o arch/powerpc/platforms/powermac/.tmp_feature.o
arch/powerpc/platforms/powermac/feature.c
arch/powerpc/platforms/powermac/feature.c:65: error: conflicting types
for 'feature_lock'
include/asm/pmac_feature.h:381: error: previous declaration of
'feature_lock' was here
arch/powerpc/platforms/powermac/feature.c:65: error: conflicting types
for 'feature_lock'
include/asm/pmac_feature.h:381: error: previous declaration of
'feature_lock' was here
diff -rup -x CVS 2.6.16-rt17/arch/powerpc/kernel/time.c rt-powerpc/arch/powerpc/kernel/time.c
--- 2.6.16-rt17/arch/powerpc/kernel/time.c 2006-04-26 18:24:28.000000000 +0900
+++ rt-powerpc/arch/powerpc/kernel/time.c 2006-07-12 13:45:31.000000000 +0900
@@ -200,6 +200,7 @@ void udelay(unsigned long usecs)
}
EXPORT_SYMBOL(udelay);
+#ifndef CONFIG_GENERIC_TIME
/*
* This version of gettimeofday has microsecond resolution.
*/
@@ -223,6 +224,7 @@ static inline void __do_gettimeofday(str
xsec = temp_stamp_xsec + mulhdu(tb_ticks, temp_tb_to_xs);
sec = xsec / XSEC_PER_SEC;
usec = (unsigned long)xsec & (XSEC_PER_SEC - 1);
+#define SCALE_XSEC(xsec, max) (((xsec) * max) / XSEC_PER_SEC)
usec = SCALE_XSEC(usec, 1000000);
tv->tv_sec = sec;
@@ -254,6 +256,7 @@ void do_gettimeofday(struct timeval *tv)
}
EXPORT_SYMBOL(do_gettimeofday);
+#endif /* !CONFIG_GENERIC_TIME */
/*
* There are two copies of tb_to_xs and stamp_xsec so that no
diff -rup -x CVS 2.6.16-rt17/include/asm-generic/bug.h rt-powerpc/include/asm-generic/bug.h
--- 2.6.16-rt17/include/asm-generic/bug.h 2006-04-26 18:24:28.000000000 +0900
+++ rt-powerpc/include/asm-generic/bug.h 2006-06-08 17:18:06.000000000 +0900
@@ -16,7 +16,9 @@
#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0)
#endif
+#ifndef __ASSEMBLY__
extern void __WARN_ON(const char *func, const char *file, const int line);
+#endif /* __ASSEMBLY__ */
#ifndef HAVE_ARCH_WARN_ON
#define WARN_ON(condition) do { \
diff -rup -x CVS 2.6.16-rt17/include/asm-powerpc/hardirq.h rt-powerpc/include/asm-powerpc/hardirq.h
--- 2.6.16-rt17/include/asm-powerpc/hardirq.h 2006-03-20 14:53:29.000000000 +0900
+++ rt-powerpc/include/asm-powerpc/hardirq.h 2006-06-08 17:18:42.000000000 +0900
@@ -11,7 +11,7 @@
* for uniformity.
*/
typedef struct {
- unsigned int __softirq_pending; /* set_bit is used on this */
+ unsigned int __softirq_pending; /* set_bit is not used on this */
unsigned int __last_jiffy_stamp;
} ____cacheline_aligned irq_cpustat_t;
diff -rup -x CVS 2.6.16-rt17/include/asm-powerpc/hw_irq.h rt-powerpc/include/asm-powerpc/hw_irq.h
--- 2.6.16-rt17/include/asm-powerpc/hw_irq.h 2006-04-26 18:24:28.000000000 +0900
+++ rt-powerpc/include/asm-powerpc/hw_irq.h 2006-07-12 13:55:15.000000000 +0900
@@ -11,7 +11,11 @@
#include <asm/ptrace.h>
#include <asm/processor.h>
-extern void timer_interrupt(struct pt_regs *);
+/*
+ * this conflicts w/ the declaration of 'timer_interrupt' in
+ * kernel/time/clockevents.c
+ */
+/* extern void timer_interrupt(struct pt_regs *); */
#ifdef CONFIG_PPC_ISERIES
diff -rup -x CVS 2.6.16-rt17/include/asm-powerpc/percpu.h rt-powerpc/include/asm-powerpc/percpu.h
--- 2.6.16-rt17/include/asm-powerpc/percpu.h 2006-03-20 14:53:29.000000000 +0900
+++ rt-powerpc/include/asm-powerpc/percpu.h 2006-06-08 21:03:28.000000000 +0900
@@ -18,11 +18,23 @@
/* Separate out the type, so (int[3], foo) works. */
#define DEFINE_PER_CPU(type, name) \
__attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name
+#define DEFINE_PER_CPU_LOCKED(type, name) \
+ __attribute__((__section__(".data.percpu"))) spinlock_t per_cpu_lock__##name##_locked = SPIN_LOCK_UNLOCKED; \
+ __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name##_locked
/* var is in discarded region: offset to particular copy we want */
#define per_cpu(var, cpu) (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset(cpu)))
#define __get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __my_cpu_offset()))
+#define per_cpu_lock(var, cpu) \
+ (*RELOC_HIDE(&per_cpu_lock__##var##_locked, __per_cpu_offset(cpu)))
+#define per_cpu_var_locked(var, cpu) \
+ (*RELOC_HIDE(&per_cpu__##var##_locked, __per_cpu_offset(cpu)))
+#define __get_cpu_lock(var, cpu) \
+ per_cpu_lock(var, cpu)
+#define __get_cpu_var_locked(var, cpu) \
+ per_cpu_var_locked(var, cpu)
+
/* A macro to avoid #include hell... */
#define percpu_modcopy(pcpudst, src, size) \
do { \
@@ -39,16 +51,27 @@ extern void setup_per_cpu_areas(void);
#define DEFINE_PER_CPU(type, name) \
__typeof__(type) per_cpu__##name
+#define DEFINE_PER_CPU_LOCKED(type, name) \
+ spinlock_t per_cpu_lock__##name##_locked = SPIN_LOCK_UNLOCKED; \
+ __typeof__(type) per_cpu__##name##_locked
#define per_cpu(var, cpu) (*((void)(cpu), &per_cpu__##var))
+#define per_cpu_var_locked(var, cpu) (*((void)(cpu), &per_cpu__##var##_locked))
#define __get_cpu_var(var) per_cpu__##var
+#define __get_cpu_lock(var, cpu) per_cpu_lock__##var##_locked
+#define __get_cpu_var_locked(var, cpu) per_cpu__##var##_locked
#endif /* SMP */
#define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name
+#define DECLARE_PER_CPU_LOCKED(type, name) \
+ extern spinlock_t per_cpu_lock__##name##_locked; \
+ extern __typeof__(type) per_cpu__##name##_locked
#define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var)
#define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var)
+#define EXPORT_PER_CPU_LOCKED_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu_lock__##var##_locked); EXPORT_SYMBOL_GPL(per_cpu__##var##_locked)
+
#else
#include <asm-generic/percpu.h>
diff -rup -x CVS 2.6.16-rt17/include/asm-powerpc/pmac_feature.h rt-powerpc/include/asm-powerpc/pmac_feature.h
--- 2.6.16-rt17/include/asm-powerpc/pmac_feature.h 2006-03-20 14:53:29.000000000 +0900
+++ rt-powerpc/include/asm-powerpc/pmac_feature.h 2006-05-10 13:52:58.000000000 +0900
@@ -378,7 +378,7 @@ extern struct macio_chip* macio_find(str
* Those are exported by pmac feature for internal use by arch code
* only like the platform function callbacks, do not use directly in drivers
*/
-extern spinlock_t feature_lock;
+extern raw_spinlock_t feature_lock;
extern struct device_node *uninorth_node;
extern u32 __iomem *uninorth_base;
diff -rup -x CVS 2.6.16-rt17/kernel/time/clockevents.c rt-powerpc/kernel/time/clockevents.c
--- 2.6.16-rt17/kernel/time/clockevents.c 2006-04-26 18:24:29.000000000 +0900
+++ rt-powerpc/kernel/time/clockevents.c 2006-07-12 13:58:28.000000000 +0900
@@ -29,6 +29,8 @@
#include <linux/percpu.h>
#include <linux/sysdev.h>
#include <linux/hrtimer.h>
+#include <linux/irq.h>
+#include <linux/profile.h>
#define MAX_CLOCK_EVENTS 4
^ permalink raw reply
* RE: PCI driver on EB8347
From: Liu Dave-r63238 @ 2006-08-11 3:40 UTC (permalink / raw)
To: rajan rai, Gala Kumar K.-galak; +Cc: linuxppc-embedded
In-Reply-To: <4DA89577C33E194ABEBC978921E858541B8E38@exchange.ingenient.net>
Rajan> I have written PCI driver which works fine along with
MPC8347 and two PCI
Rajan> card connected in a single PCI bus. When I try to communicate
same PCI card
Rajan> using PCI bridge ( PCI2050B ), Linux does detect PCI card on
Secondary bus=20
Rajan> but same driver doesn't work !!!!
PCI interrupt for secondary bus set up properly?
=20
Rajan> Do I need to enable support for second PCI host controller
at kernel level to=20
Rajan>make it work? Or I need to do something else ? I tried compiling
PPC-linux kernel
Rajan> after enabling CONFIG_85xx_PCI2 kernel doesn't compile it gives
me error while=20
Rajan>compiling "arch/ppc/syslib/ppc83xx_setup.c" Kernel version I'm
using is 2.6.13.
Why you enable CONFIG_85xx_PCI2 in kernel? It is for 85xx, but you are
using 8347 processor.
<snip>
Dave
^ permalink raw reply
* [RFC PATCH 3/4] powerpc 2.6.16-rt17: to support CONFIG_MCOUNT
From: Tsutomu OWA @ 2006-08-11 2:17 UTC (permalink / raw)
To: linux-kernel; +Cc: linuxppc-dev, mingo, tglx
In-Reply-To: <yyilkpwhvwh.wl@forest.swc.toshiba.co.jp>
Please read the previous mail's subject as [RFC PATCH 3/4] powerpc 2.6.16-rt17: to support CONFIG_MCOUNT.
Sorry about that.
thanks.
-- owa
Software Engineering Center, TOSHIBA.
^ permalink raw reply
* Realtime preemption patch on PPC
From: Ben Weintraub @ 2006-08-11 0:55 UTC (permalink / raw)
To: linuxppc-dev
(Sorry for those of you who see this message twice, it was originally
posted in the linuxppc-embedded list, but Mark Greer suggested
posting it here too)
Howdy,
I'm wondering if anyone has had success getting Ingo Molnar's realtime
preemption patch (the one here:
http://people.redhat.com/mingo/realtime-preempt/ ) working on the ppc
arch.
I'm working with patch-2.6.17-rt8 (the latest) and linux-2.6.17. The
realtime-preempt patch seems to include the generic timeofday patch, but
with no support for the ppc arch, only powerpc, so I've hacked in
support for ppc by basically replicating the powerpc arch-specific stuff
found here:
http://sr71.net/~jstultz/tod/archive/linux-2.6.17-rc3_timekeeping_C2/
broken-out/linux-2.6.17-rc3_timeofday-arch-ppc_C2.patch
I can attach my patch if anyone would like, but for all I know it could
be wildly inaccurate.
Anyhow, when I boot on an MPC8555 with my hack, I get an endless stream
of:
BUG: sleeping function called from invalid context init(1) at
arch/powerpc/math-emu/math.c:226
in_atomic():0 [00000000], irqs_disabled():1
Call Trace:
[A0BB3E90] [A000934C] show_stack+0x48/0x194 (unreliable)
[A0BB3EC0] [A001B7DC] __might_sleep+0xe8/0xf4
[A0BB3EE0] [A00136C0] do_mathemu+0x30/0x8c8
[A0BB3F00] [A00036AC] program_check_exception+0x1ac/0x514
[A0BB3F40] [A0002A08] ret_from_except_full+0x0/0x4c
Line 226 in arch/powerpc/math-emu/math.c is part of the do_mathemu()
function, and contains a call to get_user(), which calls
__might_sleep(), causing this problem.
I did find this message in the LKML archives describing a very similar
problem:
http://lkml.org/lkml/2006/2/23/312
And so tried putting a call to local_irq_enable() before the call to
do_mathemu() in program_check_excpetion(), but this causes a hard lockup
with no messages printed when I try to bring up my network interface. I
assume this means I've done something Very Bad with interrupts by adding
in local_irq_enable() at the wrong spot. I also tried adding it at the
exact same spot as the patch given by Paul in his reply, but in this
case I still get the endless stream of BUG messages.
Can anyone offer some guidance or advice?
Thanks so much,
Ben
^ permalink raw reply
* Re: Realtime preemption patch on PPC
From: Lee Revell @ 2006-08-11 1:38 UTC (permalink / raw)
To: Ben Weintraub; +Cc: linuxppc-embedded
In-Reply-To: <1155251072.5950.80.camel@localhost>
On Thu, 2006-08-10 at 16:04 -0700, Ben Weintraub wrote:
> Howdy,
>
> I'm wondering if anyone has had success getting Ingo Molnar's realtime
> preemption patch (the one here:
> http://people.redhat.com/mingo/realtime-preempt/ ) working on the ppc
> arch.
>
This is probably a better question for the -rt people and LKML than this
list.
Lee
^ permalink raw reply
* PCI driver on EB8347
From: rajan rai @ 2006-08-11 0:49 UTC (permalink / raw)
To: kumar.gala; +Cc: linuxppc-embedded
[-- Attachment #1: Type: text/plain, Size: 2322 bytes --]
I have written PCI driver which works fine along with MPC8347 and two PCI card connected in a single PCI bus. When I try to communicate same PCI card using PCI bridge ( PCI2050B ), Linux does detect PCI card on Secondary bus but same driver doesn't work !!!!
Do I need to enable support for second PCI host controller at kernel level to make it work? Or I need to do something else ? I tried compiling PPC-linux kernel after enabling CONFIG_85xx_PCI2 kernel doesn't compile it gives me error while compiling "arch/ppc/syslib/ppc83xx_setup.c" Kernel version I'm using is 2.6.13.
****** Board along with which PCI card works ************
lspci -v
/demo # lspci -v
00:1b.0 Non-VGA unclassified device: Texas Instruments: Unknown device 9065 (rev 01)
Flags: bus master, medium devsel, latency 128, IRQ 21
Memory at 9fc00000 (32-bit, prefetchable) [size=4M]
Memory at 9f000000 (32-bit, non-prefetchable) [size=8M]
I/O ports at 3ffffff0 [size=16]
Capabilities: [40] Power Management version 2
00:1c.0 Non-VGA unclassified device: Texas Instruments: Unknown device 9065 (rev 01)
Flags: bus master, medium devsel, latency 128, IRQ 18
Memory at 9ec00000 (32-bit, prefetchable) [size=4M]
Memory at 9e000000 (32-bit, non-prefetchable) [size=8M]
I/O ports at 3fffffe0 [size=16]
Capabilities: [40] Power Management version 2
****** Board along with which PCI card doesn't work ************
lspci -v
PCI devices found:
Bus 0, device 17, function 0:
Class 0604: PCI device 104c:ac28 (rev 2).
Bus 1, device 1, function 0:
Class 0000: PCI device 104c:9065 (rev 1).
Master Capable. Latency=128.
Prefetchable 32 bit memory at 0x9fc00000 [0x9fffffff].
Non-prefetchable 32 bit memory at 0x9f000000 [0x9f7fffff].
I/O at 0xfff0 [0xffff].
Bus 1, device 2, function 0:
Class 0000: PCI device 104c:9065 (rev 1).
Master Capable. Latency=128.
Prefetchable 32 bit memory at 0x9ec00000 [0x9effffff].
Non-prefetchable 32 bit memory at 0x9e000000 [0x9e7fffff].
I/O at 0xffe0 [0xffef].
Any help would be appreciated I'm running out of ideas what to do next !!!!!!!!
Regards,
-Rajan Rai
[-- Attachment #2: Type: text/html, Size: 3795 bytes --]
^ permalink raw reply
* Problem with SCC uart in UART mode on mpc8270 w/ Linux-2.6.17.6
From: Vipin.Malik @ 2006-08-11 0:55 UTC (permalink / raw)
To: linuxppc-dev
Hi,
I'm trying to use the SCC1 in uart mode on a MPC8270 under 2.6.17.4 from
kernel.org
I've turned on all SCC uarts and I can send and rx data but have an
issue:
The first time I open the port (ttyCPM2) by "cat /dev/ttyCPM2" and "cat
>/dev/ttyCPM2"
I can tx and rx fine.
The problem occurs when I close the first cat session and open it again.
This time, my TX has some sort of threshold in it. It seems that only
after a few 10's of bytes have been sent to the port (the fifo size?
Need to
check) does the scc actually send the data. After that it's all ok.
However, my rx never works after the 1st port open.
Console is on SMC1 and works fine all the time.
I'm using non-platform mode (whatever I tried to do in platform mode, my
SMC1 console stopped working/board stopped working. I would not get any
output after u-boot starts the kernel- not even the Linux version
string).
Any ideas?
TIA
Vipin
P.S. I had to hack the compat code to get the BRG's wired properly for
the SCC's, but the SCC works the 1st time and tx works (besides the
threshold
issue)- so I don't think that is the cause.
I also tried to get platform code working, but not luck. Is there any
document or email anywhere I can read that explains that setup?
^ permalink raw reply
* Re: [PATCH 3/6] ehea: queue management
From: Michael Neuling @ 2006-08-11 0:46 UTC (permalink / raw)
To: Alexey Dobriyan
Cc: Thomas Klein, netdev, linux-kernel, Christoph Raisch,
linuxppc-dev, Marcus Eder
In-Reply-To: <20060811003204.GA6935@martell.zuzino.mipt.ru>
> > > +static inline u32 map_swqe_size(u8 swqe_enc_size)
> > > +{
> > > + return 128 << swqe_enc_size;
> > > +} ^
> > > + |
> > > +static inline u32|map_rwqe_size(u8 rwqe_enc_size)
> > > +{ |
> > > + return 128 << rwqe_enc_size;
> ^
> > > +} |
> > |
> > Snap! These are ide|tical...
> |
> No, they aren't. -----+
Functionally identical.
Mikey
^ permalink raw reply
* Re: [PATCH 3/6] ehea: queue management
From: Alexey Dobriyan @ 2006-08-11 0:32 UTC (permalink / raw)
To: Michael Neuling
Cc: Thomas Klein, netdev, linux-kernel, Christoph Raisch,
linuxppc-dev, Marcus Eder
In-Reply-To: <20060811000540.200CE67B6B@ozlabs.org>
> > +static inline u32 map_swqe_size(u8 swqe_enc_size)
> > +{
> > + return 128 << swqe_enc_size;
> > +} ^
> > + |
> > +static inline u32|map_rwqe_size(u8 rwqe_enc_size)
> > +{ |
> > + return 128 << rwqe_enc_size;
^
> > +} |
> |
> Snap! These are ide|tical...
|
No, they aren't. -----+
> Name the function after what it does, not after the functions you expect
> to call it.
^ permalink raw reply
* Re: [PATCH 3/6] ehea: queue management
From: Michael Neuling @ 2006-08-11 0:05 UTC (permalink / raw)
To: Jan-Bernd Themann
Cc: Thomas Klein, netdev, linux-kernel, linux-ppc, Christoph Raisch,
Marcus Eder
In-Reply-To: <44D99F38.8010306@de.ibm.com>
Please add comments to make the code more readable, especially at the
start of functions/structures to describe what they do. A large readme
at the start of ehea_main.c which gave an overview of the driver design
would be really useful.
Comments inline below...
> +static void *ipz_qpageit_get_inc(struct ipz_queue *queue)
> +{
> + void *retvalue = ipz_qeit_get(queue);
> + queue->current_q_offset += queue->pagesize;
> + if (queue->current_q_offset > queue->queue_length) {
> + queue->current_q_offset -= queue->pagesize;
> + retvalue = NULL;
> + }
> + else if ((((u64) retvalue) & (EHEA_PAGESIZE-1)) != 0) {
> + EDEB(4, "ERROR!! not at PAGE-Boundary");
> + return NULL;
> + }
> + EDEB(7, "queue=%p retvalue=%p", queue, retvalue);
Don't redefine these debugging macros, but if so, what is EDEB?
> + return retvalue;
> +}
> +
> +static int ipz_queue_ctor(struct ipz_queue *queue,
> + const u32 nr_of_pages,
> + const u32 pagesize, const u32 qe_size,
> + const u32 nr_of_sg)
> +{
> + int f;
> + EDEB_EN(7, "nr_of_pages=%x pagesize=%x qe_size=%x",
> + nr_of_pages, pagesize, qe_size);
> + queue->queue_length = nr_of_pages * pagesize;
> + queue->queue_pages = vmalloc(nr_of_pages * sizeof(void *));
> + if (!queue->queue_pages) {
> + EDEB(4, "ERROR!! didn't get the memory");
> + return 0;
> + }
> + memset(queue->queue_pages, 0, nr_of_pages * sizeof(void *));
> +
> + for (f = 0; f < nr_of_pages; f++) {
> + (queue->queue_pages)[f] =
> + (struct ipz_page *)get_zeroed_page(GFP_KERNEL);
> + if (!(queue->queue_pages)[f]) {
> + break;
> + }
> + }
> + if (f < nr_of_pages) {
> + int g;
> + EDEB_ERR(4, "couldn't get 0ed pages queue=%p f=%x "
> + "nr_of_pages=%x", queue, f, nr_of_pages);
> + for (g = 0; g < f; g++) {
> + free_page((unsigned long)(queue->queue_pages)[g]);
> + }
> + return 0;
If you return here when calling from ehea_create_eq, I think you are
leaking the queue->queue_pages allocation (the pages they point to are
freed correctly).
Either way these allocations/deallocations seem too complicated. Can
you write to dtor so it can be called to free the structure in any state?
> + }
> + queue->current_q_offset = 0;
> + queue->qe_size = qe_size;
> + queue->act_nr_of_sg = nr_of_sg;
> + queue->pagesize = pagesize;
> + queue->toggle_state = 1;
> + EDEB_EX(7, "queue_length=%x queue_pages=%p qe_size=%x"
> + " act_nr_of_sg=%x", queue->queue_length, queue->queue_pages,
> + queue->qe_size, queue->act_nr_of_sg);
> + return 1;
> +}
> +
> +static int ipz_queue_dtor(struct ipz_queue *queue)
> +{
> + int g;
> + EDEB_EN(7, "ipz_queue pointer=%p", queue);
> + if (!queue) {
> + return 0;
> + }
> + if (!queue->queue_pages) {
> + return 0;
> + }
if (!queue || !queue->queue_pages)
return 0;
> + EDEB(7, "destructing a queue with the following properties:\n"
> + "queue_length=%x act_nr_of_sg=%x pagesize=%x qe_size=%x",
> + queue->queue_length, queue->act_nr_of_sg, queue->pagesize,
> + queue->qe_size);
> + for (g = 0; g < (queue->queue_length / queue->pagesize); g++) {
> + free_page((unsigned long)(queue->queue_pages)[g]);
> + }
> + vfree(queue->queue_pages);
> +
> + EDEB_EX(7, "queue freed!");
> + return 1;
> +}
> +
> +struct ehea_cq *ehea_cq_new(void)
> +{
> + struct ehea_cq *cq = vmalloc(sizeof(*cq));
> + if (cq)
> + memset(cq, 0, sizeof(*cq));
> + return cq;
> +}
> +
> +void ehea_cq_delete(struct ehea_cq *cq)
> +{
> + vfree(cq);
> +}
This is used in only two places. Do we need it?
If we do... can we static inline?
> +struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter,
> + int nr_of_cqe, u64 eq_handle, u32 cq_token)
> +{
> + struct ehea_cq *cq = NULL;
> + struct h_galpa gal;
> +
> + u64 *cq_handle_ref;
> + u32 act_nr_of_entries;
> + u32 act_pages;
> + u64 hret = H_HARDWARE;
> + int ipz_rc;
> + u32 counter;
> + void *vpage = NULL;
> + u64 rpage = 0;
> +
> + EDEB_EN(7, "adapter=%p nr_of_cqe=%x , eq_handle: %016lX",
> + adapter, nr_of_cqe, eq_handle);
> +
> + cq = ehea_cq_new();
> + if (!cq) {
> + cq = NULL;
> + EDEB_ERR(4, "ehea_create_cq ret=%p (-ENOMEM)", cq);
> + goto create_cq_exit0;
> + }
> +
> + cq->attr.max_nr_of_cqes = nr_of_cqe;
> + cq->attr.cq_token = cq_token;
> + cq->attr.eq_handle = eq_handle;
> +
> + cq->adapter = adapter;
> +
> + cq_handle_ref = &cq->ipz_cq_handle;
> + act_nr_of_entries = 0;
> + act_pages = 0;
> +
> + hret = ehea_h_alloc_resource_cq(adapter->handle,
> + cq,
> + &cq->attr,
> + &cq->ipz_cq_handle, &cq->galpas);
hret set twice...
> + if (hret != H_SUCCESS) {
> + EDEB_ERR(4, "ehea_h_alloc_resource_cq failed. hret=%lx", hret);
> + goto create_cq_exit1;
> + }
> +
> + ipz_rc = ipz_queue_ctor(&cq->ipz_queue, cq->attr.nr_pages,
> + EHEA_PAGESIZE, sizeof(struct ehea_cqe), 0);
> + if (!ipz_rc)
> + goto create_cq_exit2;
> +
> + hret = H_SUCCESS;
> +
> + for (counter = 0; counter < cq->attr.nr_pages; counter++) {
> + vpage = ipz_qpageit_get_inc(&cq->ipz_queue);
vpga set twice...
> + if (!vpage) {
> + EDEB_ERR(4, "ipz_qpageit_get_inc() "
> + "returns NULL adapter=%p", adapter);
> + goto create_cq_exit3;
> + }
> +
> + rpage = virt_to_abs(vpage);
> +
> + hret = ehea_h_register_rpage_cq(adapter->handle,
> + cq->ipz_cq_handle,
> + 0,
> + HIPZ_CQ_REGISTER_ORIG,
> + rpage, 1, cq->galpas.kernel);
> +
> + if (hret < H_SUCCESS) {
> + EDEB_ERR(4, "ehea_h_register_rpage_cq() failed "
> + "ehea_cq=%p hret=%lx "
> + "counter=%i act_pages=%i",
> + cq, hret, counter, cq->attr.nr_pages);
> + goto create_cq_exit3;
> + }
> +
> + if (counter == (cq->attr.nr_pages - 1)) {
> + vpage = ipz_qpageit_get_inc(&cq->ipz_queue);
> +
> + if ((hret != H_SUCCESS) || (vpage)) {
> + EDEB_ERR(4, "Registration of pages not "
> + "complete ehea_cq=%p hret=%lx",
> + cq, hret)
> + goto create_cq_exit3;
> + }
> + } else {
> + if ((hret != H_PAGE_REGISTERED) || (vpage == 0)) {
> + EDEB_ERR(4, "Registration of page failed "
> + "ehea_cq=%p hret=%lx"
> + "counter=%i act_pages=%i",
> + cq, hret, counter, cq->attr.nr_pages);
> + goto create_cq_exit3;
> + }
> + }
> + }
> +
> + ipz_qeit_reset(&cq->ipz_queue);
> + gal = cq->galpas.kernel;
> + ehea_reset_cq_ep(cq);
> + ehea_reset_cq_n1(cq);
> +
> + EDEB_EX(7, "ret=%p ", cq);
> + return cq;
> +
> +create_cq_exit3:
> + ipz_queue_dtor(&cq->ipz_queue);
> +
> +create_cq_exit2:
> + hret = ehea_h_destroy_cq(adapter->handle, cq, cq->ipz_cq_handle,
> + &cq->galpas);
> + EDEB(7, "return code of ehea_cq_destroy=%lx", hret);
> +
> +create_cq_exit1:
> + ehea_cq_delete(cq);
> +
> +create_cq_exit0:
> + EDEB_EX(7, "ret=NULL");
> + return NULL;
> +}
> +
> +int ehea_destroy_cq(struct ehea_cq *cq)
> +{
> + int ret = 0;
> + u64 adapter_handle;
> + u64 hret = H_HARDWARE;
> +
> + adapter_handle = cq->adapter->handle;
> + EDEB_EN(7, "adapter=%p cq=%p", cq->adapter, cq);
> +
> + /* deregister all previous registered pages */
> + hret = ehea_h_destroy_cq(adapter_handle, cq, cq->ipz_cq_handle,
> + &cq->galpas);
> + if (hret != H_SUCCESS) {
> + EDEB_ERR(4, "destroy CQ failed!");
> + return -EINVAL;
> + }
> + ipz_queue_dtor(&cq->ipz_queue);
> + ehea_cq_delete(cq);
> +
> + EDEB_EX(7, "ret=%x ", ret);
> + return ret;
> +}
> +
> +struct ehea_eq *ehea_eq_new(void)
> +{
> + struct ehea_eq *eq = vmalloc(sizeof(*eq));
> + if (eq)
> + memset(eq, 0, sizeof(*eq));
> + return eq;
> +}
> +
> +void ehea_eq_delete(struct ehea_eq *eq)
> +{
> + vfree(eq);
> +}
Again, is this really needed and what about static inline?
> +struct ehea_eq *ehea_create_eq(struct ehea_adapter *adapter,
> + const enum ehea_eq_type type,
> + const u32 max_nr_of_eqes, const u8 eqe_gen)
> +{
> + u64 hret = H_HARDWARE;
> + int ret = 0;
> + u32 i;
> + void *vpage = NULL;
> + struct ehea_eq *eq;
> +
> + EDEB_EN(7, "adapter=%p, max_nr_of_eqes=%x", adapter, max_nr_of_eqes);
> +
> + eq = ehea_eq_new();
> + if (!eq)
> + return NULL;
> +
> + eq->adapter = adapter;
> + eq->attr.type = type;
> + eq->attr.max_nr_of_eqes = max_nr_of_eqes;
> + eq->attr.eqe_gen = eqe_gen;
> + spin_lock_init(&eq->spinlock);
> +
> + hret = ehea_h_alloc_resource_eq(adapter->handle,
> + eq, &eq->attr, &eq->ipz_eq_handle);
> +
> + if (hret != H_SUCCESS) {
> + EDEB_ERR(4, "ehea_h_alloc_resource_eq failed. hret=%lx", hret);
> + goto free_eq_mem;
> + }
> +
> + ret = ipz_queue_ctor(&eq->ipz_queue, eq->attr.nr_pages,
> + EHEA_PAGESIZE, sizeof(struct ehea_eqe), 0);
> + if (!ret) {
> + EDEB_ERR(4, "can't allocate EQ pages");
> + goto alloc_pages_failed;
> + }
> +
> + for (i = 0; i < eq->attr.nr_pages; i++) {
> + u64 rpage;
> +
> + if (!(vpage = ipz_qpageit_get_inc(&eq->ipz_queue))) {
> + hret = H_RESOURCE;
> + goto register_page_failed;
> + }
> +
> + rpage = virt_to_abs(vpage);
> +
> + hret = ehea_h_register_rpage_eq(adapter->handle,
> + eq->ipz_eq_handle,
> + 0,
> + HIPZ_EQ_REGISTER_ORIG,
> + rpage, 1);
> +
> + if (i == (eq->attr.nr_pages - 1)) {
> + /* last page */
> + vpage = ipz_qpageit_get_inc(&eq->ipz_queue);
> + if ((hret != H_SUCCESS) || (vpage)) {
> + goto register_page_failed;
> + }
> + } else {
> + if ((hret != H_PAGE_REGISTERED) || (!vpage)) {
> + goto register_page_failed;
> + }
> + }
> + }
> +
> + ipz_qeit_reset(&eq->ipz_queue);
> +
> + EDEB_EX(7, "hret=%lx", hret);
> + return eq;
> +
> +register_page_failed:
> + ipz_queue_dtor(&eq->ipz_queue);
> +
> +alloc_pages_failed:
> + ehea_h_destroy_eq(adapter->handle, eq, eq->ipz_eq_handle, &eq->galpas);
> +free_eq_mem:
> + ehea_eq_delete(eq);
> +
> + EDEB_EX(7, "return with error hret=%lx", hret);
> + return NULL;
> +}
> +
> +void *ehea_poll_eq(struct ehea_eq *eq)
> +{
> + void *eqe = NULL;
> + unsigned long flags = 0;
> +
> + EDEB_EN(7, "adapter=%p eq=%p", eq->adapter, eq);
> +
> + spin_lock_irqsave(&eq->spinlock, flags);
> + eqe = ipz_eqit_eq_get_inc_valid(&eq->ipz_queue);
> + spin_unlock_irqrestore(&eq->spinlock, flags);
> +
> + EDEB_EX(7, "eqe=%p", eqe);
> +
> + return eqe;
> +}
> +
> +int ehea_destroy_eq(struct ehea_eq *eq)
> +{
> + unsigned long flags = 0;
> + u64 hret = H_HARDWARE;
> +
> + EDEB_EN(7, "adapter=%p eq=%p", eq->adapter, eq);
> +
> + spin_lock_irqsave(&eq->spinlock, flags);
> +
> + hret = ehea_h_destroy_eq(eq->adapter->handle, eq, eq->ipz_eq_handle,
> + &eq->galpas);
> + spin_unlock_irqrestore(&eq->spinlock, flags);
> +
> + if (hret != H_SUCCESS) {
> + EDEB_ERR(4, "Failed freeing EQ resources. hret=%lx", hret);
> + return -EINVAL;
> + }
> + ipz_queue_dtor(&eq->ipz_queue);
> + ehea_eq_delete(eq);
> + EDEB_EX(7, "");
> +
> + return 0;
> +}
> +
> +struct ehea_qp *ehea_qp_new(void) {
> + struct ehea_qp *qp = vmalloc(sizeof(*qp));
> + if (qp != 0) {
if (qp) ??
> + memset(qp, 0, sizeof(*qp));
> + }
> + return qp;
> +}
> +
> +void ehea_qp_delete(struct ehea_qp *qp)
> +{
> + vfree(qp);
> +}
> +
> +/**
> + * allocates memory for a queue and registers pages in phyp
> + */
> +int ehea_qp_alloc_register(struct ehea_qp *qp,
> + struct ipz_queue *ipz_queue,
> + int nr_pages,
> + int wqe_size,
> + int act_nr_sges,
> + struct ehea_adapter *adapter, int h_call_q_selector)
> +{
> + u64 hret = H_HARDWARE;
> + u64 rpage = 0;
> + int iret = 0;
> + int cnt = 0;
> + void *vpage = NULL;
> +
> + iret = ipz_queue_ctor(ipz_queue,
> + nr_pages, EHEA_PAGESIZE, wqe_size, act_nr_sges);
> + if (!iret) {
> + EDEB_ERR(4, "Cannot allocate page for queue. iret=%x", iret);
> + return -ENOMEM;
> + }
> +
> + EDEB(7, "queue_size=%x, alloc_len=%x, toggle_state=%d",
> + ipz_queue->qe_size,
> + ipz_queue->queue_length, ipz_queue->toggle_state);
> +
> + for (cnt = 0; cnt < nr_pages; cnt++) {
> + vpage = ipz_qpageit_get_inc(ipz_queue);
> + if (!vpage) {
> + EDEB_ERR(4, "SQ ipz_qpageit_get_inc() "
> + "failed p_vpage= %p", vpage);
> + goto qp_alloc_register_exit0;
> + }
> + rpage = virt_to_abs(vpage);
> +
> + hret = ehea_h_register_rpage_qp(adapter->handle,
> + qp->ipz_qp_handle,
> + 0,
> + h_call_q_selector,
> + rpage,
> + 1, qp->galpas.kernel);
> +
> + if (hret < H_SUCCESS) {
> + EDEB_ERR(4, "ehea_h_register_rpage_qp failed. hret=%lx"
,
> + hret);
> + goto qp_alloc_register_exit0;
> + }
> + }
> + ipz_qeit_reset(ipz_queue);
> +
> + return 0;
> +
> +qp_alloc_register_exit0:
> + ipz_queue_dtor(ipz_queue);
> + return -EINVAL;
> +}
> +
> +static inline u32 map_swqe_size(u8 swqe_enc_size)
> +{
> + return 128 << swqe_enc_size;
> +}
> +
> +static inline u32 map_rwqe_size(u8 rwqe_enc_size)
> +{
> + return 128 << rwqe_enc_size;
> +}
Snap! These are identical...
Name the function after what it does, not after the functions you expect
to call it.
> +
> +struct ehea_qp *ehea_create_qp(struct ehea_adapter *adapter,
> + u32 pd, struct ehea_qp_init_attr *init_attr)
> +{
> + struct ehea_qp *qp;
> + u64 hret = H_HARDWARE;
> +
> + u32 wqe_size_in_bytes_sq = 0;
> + u32 wqe_size_in_bytes_rq1 = 0;
> + u32 wqe_size_in_bytes_rq2 = 0;
> + u32 wqe_size_in_bytes_rq3 = 0;
> +
> + int ret = -1;
> +
> + EDEB_EN(7, "init_attr=%p", init_attr);
> +
> + qp = ehea_qp_new();
> +
> + if (!qp) {
> + EDEB_ERR(4, "pd=%X not enough memory to alloc qp", pd);
> + return NULL;
> + }
> + qp->adapter = adapter;
> +
> + EDEB(7, "send_ehea_cq->ipz_cq_handle=0x%lX"
> + "recv_ehea_cq->ipz_cq_handle=0x%lX", init_attr->send_cq_handle,
> + init_attr->recv_cq_handle);
> +
> +
> + hret = ehea_h_alloc_resource_qp(adapter->handle, qp,
> + init_attr,
> + pd,
> + &qp->ipz_qp_handle,
> + &qp->galpas);
> +
> + if (hret != H_SUCCESS) {
> + EDEB_ERR(4, "ehea_h_alloc_resource_qp failed. hret=%lx", hret);
> + goto create_qp_exit1;
> + }
> +
> + wqe_size_in_bytes_sq = map_swqe_size(init_attr->act_wqe_size_enc_sq);
> + EDEB(7, "SWQE SG %d", init_attr->wqe_size_enc_sq);
> +
> + wqe_size_in_bytes_rq1 = map_rwqe_size(init_attr->act_wqe_size_enc_rq1);
> + wqe_size_in_bytes_rq2 = map_rwqe_size(init_attr->act_wqe_size_enc_rq2);
> + wqe_size_in_bytes_rq3 = map_rwqe_size(init_attr->act_wqe_size_enc_rq3);
> +
> + EDEB(7, "SQ pages: %d, SQ WQE size:%d, max SWQE size enc: %d",
> + init_attr->nr_sq_pages,
> + wqe_size_in_bytes_sq, init_attr->act_wqe_size_enc_sq);
> +
> + EDEB(7, "RQ1 pages: %d, RQ1 WQE size:%d, max RWQE size enc: %d",
> + init_attr->nr_rq1_pages,
> + wqe_size_in_bytes_rq1, init_attr->act_wqe_size_enc_rq1);
> +
> + EDEB(7, "RQ2 pages: %d, RQ2 WQE size:%d, max RWQE size enc: %d",
> + init_attr->nr_rq2_pages,
> + wqe_size_in_bytes_rq2, init_attr->act_wqe_size_enc_rq2);
> +
> + EDEB(7, "RQ3 pages: %d, RQ3 WQE size:%d, max RWQE size enc: %d",
> + init_attr->nr_rq3_pages,
> + wqe_size_in_bytes_rq3, init_attr->act_wqe_size_enc_rq3);
> +
> + ret = ehea_qp_alloc_register(qp,
> + &qp->ipz_squeue,
> + init_attr->nr_sq_pages,
> + wqe_size_in_bytes_sq,
> + init_attr->act_wqe_size_enc_sq, adapter,
> + 0);
> + if (ret < H_SUCCESS) {
> + EDEB_ERR(4, "can't register for sq hret=%x", ret);
> + goto create_qp_exit2;
> + }
> +
> + ret = ehea_qp_alloc_register(qp,
> + &qp->ipz_rqueue1,
> + init_attr->nr_rq1_pages,
> + wqe_size_in_bytes_rq1,
> + init_attr->act_wqe_size_enc_rq1,
> + adapter, 1);
> +
> + if (ret < 0) {
> + EDEB_ERR(4, "can't register for rq1 hret=%x", ret);
> + goto create_qp_exit3;
> + }
> +
> + if (init_attr->rq_count > 1) {
> + ret = ehea_qp_alloc_register(qp,
> + &qp->ipz_rqueue2,
> + init_attr->nr_rq2_pages,
> + wqe_size_in_bytes_rq2,
> + init_attr->act_wqe_size_enc_rq2,
> + adapter, 2);
> +
> + if (ret < 0) {
> + EDEB_ERR(4, "can't register for rq2 hret=%x", ret);
> + goto create_qp_exit4;
> + }
> + }
> +
> + if (init_attr->rq_count > 2) {
> + ret = ehea_qp_alloc_register(qp,
> + &qp->ipz_rqueue3,
> + init_attr->nr_rq3_pages,
> + wqe_size_in_bytes_rq3,
> + init_attr->act_wqe_size_enc_rq3,
> + adapter, 3);
> +
> + if (ret != 0) {
> + EDEB_ERR(4, "can't register for rq3 hret=%x", ret);
> + goto create_qp_exit5;
> + }
> + }
> +
> + qp->init_attr = *init_attr;
> +
> + EDEB_EX(7, "");
> + return qp;
> +
> +create_qp_exit5:
> + ipz_queue_dtor(&qp->ipz_rqueue2);
> +
> +create_qp_exit4:
> + ipz_queue_dtor(&qp->ipz_rqueue1);
> +
> +create_qp_exit3:
> + ipz_queue_dtor(&qp->ipz_squeue);
> +
> +create_qp_exit2:
> + hret = ehea_h_destroy_qp(adapter->handle, qp, qp->ipz_qp_handle,
> + &qp->galpas);
> +
> +create_qp_exit1:
> + ehea_qp_delete(qp);
> +
> + EDEB_EX(7, "hret=NULL");
> + return NULL;
> +
> +}
> +
> +int ehea_destroy_qp(struct ehea_qp *qp)
> +{
> + int ret = 0;
> + u64 hret = H_HARDWARE;
> + struct ehea_qp_init_attr *qp_attr = &qp->init_attr;
> + EDEB_EX(7, "");
> +
> + hret = ehea_h_destroy_qp(qp->adapter->handle, qp, qp->ipz_qp_handle,
> + &qp->galpas);
> + if (hret != H_SUCCESS) {
> + EDEB_ERR(4, "destroy QP failed!");
> + ret = -EINVAL;
> + }
> +
> + ipz_queue_dtor(&qp->ipz_squeue);
> + ipz_queue_dtor(&qp->ipz_rqueue1);
> +
> + if(qp_attr->rq_count > 1)
> + ipz_queue_dtor(&qp->ipz_rqueue2);
> + if(qp_attr->rq_count > 2)
> + ipz_queue_dtor(&qp->ipz_rqueue3);
> + ehea_qp_delete(qp);
> +
> + EDEB_EX(7, "hret=%lx", hret);
> +
> + return ret;
> +}
> +
> +int ehea_reg_mr_adapter(struct ehea_adapter *adapter)
> +{
> + int i = 0;
> + int k = 0;
> + u64 hret = H_HARDWARE;
> + u64 start = KERNELBASE;
> + u64 end = (u64) high_memory;
> + u64 nr_pages = (end - start) / PAGE_SIZE;
> + u32 acc_ctrl = EHEA_MR_ACC_CTRL;
> + u64 pt_abs = 0;
> + u64 *pt;
> +
> + EDEB_EN(7, "adapter=%p", adapter);
> + pt = kzalloc(PAGE_SIZE, GFP_KERNEL);
> + if (!pt) {
> + EDEB_ERR(4, "allocating page failed");
> + return -EINVAL;
> + }
> + pt_abs = virt_to_abs(pt);
> +
> + hret = ehea_h_alloc_resource_mr(adapter->handle,
> + start,
> + end - start,
> + acc_ctrl,
> + adapter->pd,
> + &adapter->mr.handle,
> + &adapter->mr.lkey);
> + if (hret != H_SUCCESS) {
> + EDEB_EX(4, "Error: hret=%lX\n", hret);
> + return -EINVAL;
> + }
> +
> + adapter->mr.vaddr = KERNELBASE;
> +
> + while (nr_pages > 0) {
> + if (nr_pages > 1) {
> + u64 num_pages = min(nr_pages, (u64)512);
> + for (i = 0; i < num_pages; i++)
> + pt[i] = virt_to_abs((void *)(((u64)start)
> + + ((k++) *
> + PAGE_SIZE)));
> +
> + hret = ehea_h_register_rpage_mr(adapter->handle,
> + adapter->mr.handle,
> + 0,
> + 0,
> + (u64)pt_abs,
> + num_pages);
They probably don't all need their own line.
> + nr_pages -= num_pages;
> + } else {
> + u64 abs_adr = virt_to_abs((void *)(((u64)start)
> + + (k * PAGE_SIZE)));
> + hret = ehea_h_register_rpage_mr(adapter->handle,
> + adapter->mr.handle,
> + 0,
> + 0,
> + abs_adr,
> + 1);
Ditto.
> + nr_pages--;
> + }
> +
> + if ((hret != H_SUCCESS) && (hret != H_PAGE_REGISTERED)) {
> + ehea_h_free_resource_mr(adapter->handle,
> + adapter->mr.handle);
> + EDEB_EX(4, " register rpage_mr: hret=%lX\n", hret);
> + return -EINVAL;
> + }
> + }
> +
> + if (hret != H_SUCCESS) {
> + ehea_h_free_resource_mr(adapter->handle, adapter->mr.handle);
> + EDEB_EX(4, " register rpage_mr failed for last page: hret=%lX",
> + hret);
> + return -EINVAL;
> + }
> +
> + EDEB_EX(7, "lkey=0x%X, mr_handle=0x%lX", adapter->mr.lkey,
> + adapter->mr.handle);
> + return 0;
> +}
> +
> +int ehea_reg_mr_pages(struct ehea_adapter *adapter,
> + struct ehea_mr *mr,
> + u64 start, u64 *pt, int nr_pages)
> +{
> + u64 hret = H_HARDWARE;
> + u32 acc_ctrl = EHEA_MR_ACC_CTRL;
> +
> + u64 pt_abs = virt_to_abs(pt);
> + u64 first_page = pt[0];
> +
> + hret = ehea_h_alloc_resource_mr(adapter->handle,
> + start,
> + PAGE_SIZE * nr_pages,
> + acc_ctrl,
> + adapter->pd,
> + &mr->handle,
> + &mr->lkey);
> + if (hret != H_SUCCESS) {
> + EDEB_EX(4, "Error: hret=%lX\n", hret);
> + return -EINVAL;
> + }
> +
> + if (nr_pages > 1)
> + hret = ehea_h_register_rpage_mr(adapter->handle,
> + mr->handle,
> + 0,
> + 0,
> + (u64)pt_abs,
> + nr_pages);
> + else
> + hret = ehea_h_register_rpage_mr(adapter->handle,
> + mr->handle,
> + 0,
> + 0,
> + first_page,
> + 1);
hret = ehea_h_register_rpage_mr(adapter->handle, mr->handle, 0,
0, (nr_pages > 1)?(u64)pt_abs:first_page,
nr_pages);
Simpler?
Or get ehea_h_register_rpage_mr to do this for you? You seem to do this
same decode twice?
> +
> + if (hret != H_SUCCESS) {
> + ehea_h_free_resource_mr(adapter->handle, mr->handle);
> + EDEB_EX(4, " register rpage_mr failed for last page:"
> + "hret=%lX\n", hret);
> + return -EINVAL;
> + }
> + mr->vaddr = start;
> +
> + EDEB_EX(7, "");
> + return 0;
> +}
> +
> +
> +
> +int ehea_dereg_mr_adapter(struct ehea_adapter *adapter)
> +{
> + u64 hret = H_HARDWARE;
> + EDEB_EN(7, "adapter=%p", adapter);
> + hret = ehea_h_free_resource_mr(adapter->handle, adapter->mr.handle);
> + if (hret != H_SUCCESS) {
> + EDEB_EX(4, "deregistering memory region failed");
> + return -EINVAL;
> + }
> + EDEB_EX(7, "");
> + return 0;
> +}
> --- linux-2.6.18-rc4-orig/drivers/net/ehea/ehea_qmr.h 1969-12-31 16:00:00.000
000000 -0800
> +++ kernel/drivers/net/ehea/ehea_qmr.h 2006-08-08 23:59:38.108463416 -
0700
> @@ -0,0 +1,381 @@
> +/*
> + * linux/drivers/net/ehea/ehea_qmr.h
> + *
> + * eHEA ethernet device driver for IBM eServer System p
> + *
> + * (C) Copyright IBM Corp. 2006
> + *
> + * Authors:
> + * Christoph Raisch <raisch@de.ibm.com>
> + * Jan-Bernd Themann <themann@de.ibm.com>
> + * Heiko-Joerg Schick <schickhj@de.ibm.com>
> + * Thomas Klein <tklein@de.ibm.com>
> + *
> + *
> + * 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, or (at your option)
> + * any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
> + */
> +
> +#ifndef __EHEA_QMR_H__
> +#define __EHEA_QMR_H__
> +
> +#include "ehea.h"
> +#include "ehea_hw.h"
> +
> +/* Use of WR_ID field for EHEA */
> +#define EHEA_WR_ID_COUNT EHEA_BMASK_IBM(0, 19)
> +#define EHEA_WR_ID_TYPE EHEA_BMASK_IBM(20, 23)
> +#define EHEA_SWQE2_TYPE 0x1
> +#define EHEA_SWQE3_TYPE 0x2
> +#define EHEA_RWQE2_TYPE 0x3 /* RQ2 */
> +#define EHEA_RWQE3_TYPE 0x4 /* RQ3 */
> +#define EHEA_WR_ID_INDEX EHEA_BMASK_IBM(24, 47)
> +#define EHEA_WR_ID_REFILL EHEA_BMASK_IBM(48, 63)
> +
> +struct ehea_vsgentry {
> + u64 vaddr;
> + u32 l_key;
> + u32 len;
> +};
> +
> +/* maximum number of sg entries allowed in a WQE */
> +#define EHEA_MAX_WQE_SG_ENTRIES 252
> +#define SWQE2_MAX_IMM (0xD0 - 0x30) /* (160-14) ? */
> +#define SWQE3_MAX_IMM 224
> +
> +/* tx control flags for swqe */
> +#define EHEA_SWQE_CRC 0x8000
> +#define EHEA_SWQE_IP_CHECKSUM 0x4000
> +#define EHEA_SWQE_TCP_CHECKSUM 0x2000
> +#define EHEA_SWQE_TSO 0x1000
> +#define EHEA_SWQE_SIGNALLED_COMPLETION 0x0800
> +#define EHEA_SWQE_VLAN_INSERT 0x0400
> +#define EHEA_SWQE_IMM_DATA_PRESENT 0x0200
> +#define EHEA_SWQE_DESCRIPTORS_PRESENT 0x0100
> +#define EHEA_SWQE_WRAP_CTL_REC 0x0080
> +#define EHEA_SWQE_WRAP_CTL_FORCE 0x0040
> +#define EHEA_SWQE_BIND 0x0020
> +#define EHEA_SWQE_PURGE 0x0010
> +
> +#define SWQE_HEADER_SIZE 32
This is never used...
Would be nice to document some of the names here. What are SWQE, RWQE,
WQE, CQE, IPZ etc?
> +
> +struct ehea_swqe {
> + u64 wr_id;
> + u16 tx_control;
> + u16 vlan_tag;
> + u8 reserved1;
> + u8 ip_start;
> + u8 ip_end;
> + u8 immediate_data_length;
> + u8 tcp_offset;
> + u8 reserved2;
> + u16 tcp_end;
> + u8 wrap_tag;
> + u8 descriptors; /* number of valid descriptors in WQE */
> + u16 reserved3;
> + u16 reserved4;
> + u16 mss;
> + u32 reserved5;
> + union {
> + /* Send WQE Format 1 */
> + struct {
> + struct ehea_vsgentry sg_list[EHEA_MAX_WQE_SG_ENTRIES];
> + } no_immediate_data;
> +
> + /* Send WQE Format 2 */
> + struct {
> + struct ehea_vsgentry sg_entry;
> + /* 0x30 */
> + u8 immediate_data[SWQE2_MAX_IMM];
> + /* 0xd0 */
> + struct ehea_vsgentry sg_list[EHEA_MAX_WQE_SG_ENTRIES-1]
;
> + } immdata_desc __attribute__ ((packed));
> +
> + /* Send WQE Format 3 */
> + struct {
> + u8 immediate_data[SWQE3_MAX_IMM];
> + } immdata_nodesc;
> + } u;
> +};
> +
> +struct ehea_rwqe {
> + u64 wr_id; /* work request ID */
> + u8 reserved1[5];
> + u8 data_segments;
> + u16 reserved2;
> + u64 reserved3;
> + u64 reserved4;
> + struct ehea_vsgentry sg_list[EHEA_MAX_WQE_SG_ENTRIES];
> +};
> +
> +#define EHEA_CQE_VLAN_TAG_XTRACT 0x0400
> +
> +#define EHEA_CQE_TYPE_RQ 0x60
> +#define EHEA_CQE_STAT_ERR_MASK 0x7300
> +#define EHEA_CQE_STAT_ERR_TCP 0x4000
> +
> +struct ehea_cqe {
> + u64 wr_id; /* work request ID from WQE */
> + u8 type;
> + u8 valid;
> + u16 status;
> + u16 reserved1;
> + u16 num_bytes_transfered;
> + u16 vlan_tag;
> + u16 inet_checksum_value;
> + u8 reserved2;
> + u8 header_length;
> + u16 reserved3;
> + u16 page_offset;
> + u16 wqe_count;
> + u32 qp_token;
> + u32 timestamp;
> + u32 reserved4;
> + u64 reserved5[3];
> +};
> +
> +#define EHEA_EQE_VALID EHEA_BMASK_IBM(0, 0)
> +#define EHEA_EQE_IS_CQE EHEA_BMASK_IBM(1, 1)
> +#define EHEA_EQE_IDENTIFIER EHEA_BMASK_IBM(2, 7)
> +#define EHEA_EQE_QP_CQ_NUMBER EHEA_BMASK_IBM(8, 31)
> +#define EHEA_EQE_QP_TOKEN EHEA_BMASK_IBM(32, 63)
> +#define EHEA_EQE_CQ_TOKEN EHEA_BMASK_IBM(32, 63)
> +#define EHEA_EQE_KEY EHEA_BMASK_IBM(32, 63)
3 the same here?
> +#define EHEA_EQE_PORT_NUMBER EHEA_BMASK_IBM(56, 63)
> +#define EHEA_EQE_EQ_NUMBER EHEA_BMASK_IBM(48, 63)
> +#define EHEA_EQE_SM_ID EHEA_BMASK_IBM(48, 63)
2 the same here?
> +#define EHEA_EQE_SM_MECH_NUMBER EHEA_BMASK_IBM(48, 55)
> +#define EHEA_EQE_SM_PORT_NUMBER EHEA_BMASK_IBM(56, 63)
> +
> +struct ehea_eqe {
> + u64 entry;
> +};
ehea_ege.. what is that and why a struct if only 1 item? Comments
please.
In ehea_main.c you use this with a ehea_poll_eq which returns a void *
Mostly you cast to a (struct ehea_eqe *) but you don't need to.
> +
> +static inline void *ipz_qeit_calc(struct ipz_queue *queue, u64 q_offset)
> +{
> + struct ipz_page *current_page = NULL;
> + if (q_offset >= queue->queue_length)
> + q_offset -= queue->queue_length;
> + current_page = (queue->queue_pages)[q_offset >> EHEA_PAGESHIFT];
> + return ¤t_page->entries[q_offset & (EHEA_PAGESIZE - 1)];
> +}
> +
> +static inline void *ipz_qeit_get(struct ipz_queue *queue)
> +{
> + return ipz_qeit_calc(queue, queue->current_q_offset);
> +}
> +
> +static inline void ipz_qeit_inc(struct ipz_queue *queue)
> +{
> + queue->current_q_offset += queue->qe_size;
> + if (queue->current_q_offset >= queue->queue_length) {
> + queue->current_q_offset = 0;
> + /* toggle the valid flag */
> + queue->toggle_state = (~queue->toggle_state) & 1;
> + }
> +}
> +
> +static inline void *ipz_qeit_get_inc(struct ipz_queue *queue)
> +{
> + void *retvalue = ipz_qeit_get(queue);
> + ipz_qeit_inc(queue);
> + EDEB(8, "queue=%p retvalue=%p new current_q_addr=%lx qe_size=%x",
> + queue, retvalue, queue->current_q_offset, queue->qe_size);
> +
> + return retvalue;
> +}
> +
> +static inline void *ipz_qeit_get_inc_valid(struct ipz_queue *queue)
> +{
> + struct ehea_cqe *retvalue = ipz_qeit_get(queue);
> + void *pref;
> + u8 valid = retvalue->valid;
> + if ((valid >> 7) == (queue->toggle_state & 1)) {
> + /* this is a good one */
> + ipz_qeit_inc(queue);
> + pref = ipz_qeit_calc(queue, queue->current_q_offset);
> + prefetch(pref);
> + prefetch(pref + 128);
> + } else
> + retvalue = NULL;
> + return retvalue;
> +}
> +
> +static inline void *ipz_qeit_get_valid(struct ipz_queue *queue)
> +{
> + u8 valid = 0;
> +
> + struct ehea_cqe *retvalue = ipz_qeit_get(queue);
> + void *pref;
> + pref = ipz_qeit_calc(queue, queue->current_q_offset);
> + prefetch(pref);
> + prefetch(pref + 128);
> + prefetch(pref + 256);
> + valid = retvalue->valid;
> + if (!((valid >> 7) == (queue->toggle_state & 1)))
> + retvalue = NULL;
> + return retvalue;
> +}
> +
> +static inline void *ipz_qeit_reset(struct ipz_queue *queue)
> +{
> + queue->current_q_offset = 0;
> + return ipz_qeit_get(queue);
> +}
> +
> +static inline void *ipz_qeit_eq_get_inc(struct ipz_queue *queue)
> +{
> + void *retvalue = NULL;
> + u64 last_entry_in_q = queue->queue_length - queue->qe_size;
> +
> + retvalue = ipz_qeit_get(queue);
> + queue->current_q_offset += queue->qe_size;
> + if (queue->current_q_offset > last_entry_in_q) {
> + queue->current_q_offset = 0;
> + queue->toggle_state = (~queue->toggle_state) & 1;
> + }
> +
> + EDEB(7, "queue=%p retvalue=%p new current_q_offset=%lx qe_size=%x",
> + queue, retvalue, queue->current_q_offset, queue->qe_size);
> +
> + return retvalue;
> +}
> +
> +static inline void *ipz_eqit_eq_get_inc_valid(struct ipz_queue *queue)
> +{
> + void *retvalue = ipz_qeit_get(queue);
> + u32 qe = *(u8 *) retvalue;
> + EDEB(7, "ipz_eqit_eq_get_inc_valid qe=%x", qe);
> + if ((qe >> 7) == (queue->toggle_state & 1))
> + ipz_qeit_eq_get_inc(queue);
> + else
> + retvalue = NULL;
> + return retvalue;
> +}
> +
> +static inline struct ehea_rwqe *ehea_get_next_rwqe(struct ehea_qp *qp,
> + int rq_nr)
> +{
> +
> + struct ehea_rwqe *wqe_p = NULL;
> + struct ipz_queue *queue = NULL;
> + struct ehea_qp *my_qp = qp;
> + EDEB_EN(8, "QP=%p, RQ_nr=%d", qp, rq_nr);
> +
> + if (rq_nr == 1)
> + queue = &my_qp->ipz_rqueue1;
> + else if (rq_nr == 2)
> + queue = &my_qp->ipz_rqueue2;
> + else
> + queue = &my_qp->ipz_rqueue3;
> + wqe_p = (struct ehea_rwqe *)ipz_qeit_get_inc(queue);
> +
> + EDEB_EX(8, "&RWQE=%p, queue=%p", wqe_p, queue);
> + return wqe_p;
> +}
> +
> +static inline struct ehea_swqe *ehea_get_swqe(struct ehea_qp *my_qp,
> + int *wqe_index)
> +{
> + struct ipz_queue *queue = &my_qp->ipz_squeue;
> + struct ehea_swqe *wqe_p = NULL;
> + EDEB_EN(7, "QP=%p, queue=%p", my_qp, &my_qp->ipz_squeue);
> + *wqe_index = (queue->current_q_offset) >> (7 + EHEA_SG_SQ);
> + wqe_p = (struct ehea_swqe *)ipz_qeit_get_inc(&my_qp->ipz_squeue);
> + EDEB_EX(7, "");
> + return wqe_p;
> +}
> +
> +static inline void ehea_post_swqe(struct ehea_qp *my_qp, struct ehea_swqe *s
wqe)
> +{
> +
> + EDEB_EN(7, "QP=%p, SWQE=%p", my_qp, swqe);
> + EDEB(6, "SWQE workreqid = 0x%lX, imm_data_len=%d, descriptors=%d",
> + (u64) swqe->wr_id, swqe->immediate_data_length, swqe->descriptors)
;
> + iosync();
> + ehea_update_sqa(my_qp, 1);
> + EDEB_EX(7, "");
> +}
> +
> +static inline struct ehea_cqe *ehea_poll_rq1(struct ehea_qp *qp, int *wqe_in
dex)
> +{
> + struct ipz_queue *queue = &qp->ipz_rqueue1;
> + struct ehea_cqe *cqe = NULL;
> +
> + EDEB_EN(7, "QP=%p, RQ1 toggle state = %d, current_q_offset=%lx", qp,
> + queue->toggle_state, queue->current_q_offset);
> + *wqe_index = (queue->current_q_offset) >> (7 + EHEA_SG_RQ1);
> + cqe = (struct ehea_cqe *)ipz_qeit_get_valid(queue);
> + EDEB_EX(7, "cqe=%p, new toggle state %d, wqe_index = %d",
> + cqe, queue->toggle_state, *wqe_index);
> + return cqe;
> +}
> +
> +static inline void ehea_inc_rq1(struct ehea_qp *qp)
> +{
> + struct ipz_queue *queue = &qp->ipz_rqueue1;
> + ipz_qeit_inc(queue);
> +}
> +
> +static inline struct ehea_cqe *ehea_poll_cq(struct ehea_cq *my_cq)
> +{
> +
> + struct ehea_cqe *wqe_p = NULL;
> + EDEB_EN(7, "CQ=%p", my_cq);
> +
> + EDEB(7, "queue_element_size=%x, alloc_len=%x, queue=%p",
> + my_cq->ipz_queue.qe_size,
> + my_cq->ipz_queue.queue_length, &my_cq->ipz_queue);
> + wqe_p = (struct ehea_cqe *)ipz_qeit_get_inc_valid(&my_cq->ipz_queue);
> +
> + EDEB_EX(7, "wqe_p=%p", wqe_p);
> + return wqe_p;
> +};
Can we stick all these functions in the .c and put only the prototypes here?
> +
> +#define HIPZ_CQ_REGISTER_ORIG 0
> +#define HIPZ_EQ_REGISTER_ORIG 0
> +
> +enum ehea_eq_type {
> + EHEA_EQ = 0, /* event queue */
> + EHEA_NEQ /* notification event queue */
> +};
> +
> +struct ehea_eq *ehea_create_eq(struct ehea_adapter *adapter,
> + enum ehea_eq_type type,
> + const u32 length, const u8 eqe_gen);
> +
> +int ehea_destroy_eq(struct ehea_eq *eq);
> +
> +void *ehea_poll_eq(struct ehea_eq *eq);
> +
> +struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter, int cqe,
> + u64 eq_handle, u32 cq_token);
> +
> +int ehea_destroy_cq(struct ehea_cq *cq);
> +
> +
> +struct ehea_qp *ehea_create_qp(struct ehea_adapter * adapter,
> + u32 pd,
> + struct ehea_qp_init_attr *init_attr);
> +
> +int ehea_destroy_qp(struct ehea_qp *qp);
> +
> +int ehea_reg_mr_adapter(struct ehea_adapter *adapter);
> +int ehea_dereg_mr_adapter(struct ehea_adapter *adapter);
> +
> +int ehea_reg_mr_pages(struct ehea_adapter *adapter,
> + struct ehea_mr *mr,
> + u64 start, u64 *pt, int nr_pages);
> +
> +#endif /* __EHEA_QMR_H__ */
> --- linux-2.6.18-rc4-orig/drivers/net/ehea/ehea_ethtool.c 1969-12-31 16:0
0:00.000000000 -0800
> +++ kernel/drivers/net/ehea/ehea_ethtool.c 2006-08-08 23:59:38.092465848 -
0700
Why is the ethtool stuff in the queue management patch?
> @@ -0,0 +1,325 @@
> +/*
> + * linux/drivers/net/ehea/ehea_ethtool.c
> + *
> + * eHEA ethernet device driver for IBM eServer System p
> + *
> + * (C) Copyright IBM Corp. 2006
> + *
> + * Authors:
> + * Christoph Raisch <raisch@de.ibm.com>
> + * Jan-Bernd Themann <themann@de.ibm.com>
> + * Heiko-Joerg Schick <schickhj@de.ibm.com>
> + * Thomas Klein <tklein@de.ibm.com>
> + *
> + *
> + * 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, or (at your option)
> + * any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
> + */
> +
> +#include "ehea.h"
> +#include "ehea_phyp.h"
> +
> +
> +static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *c
md)
> +{
> + u64 hret = H_HARDWARE;
> + struct ehea_port *port = (struct ehea_port*)dev->priv;
> + struct ehea_adapter *adapter = port->adapter;
> + struct hcp_query_ehea_port_cb_4 *cb4 = NULL;
> +
> + EDEB_EN(7, "net_device=%p", dev);
> +
> + cb4 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
> + if(!cb4) {
> + EDEB_ERR(4, "No memory for cb4");
> + goto get_settings_exit;
> + }
> +
> + hret = ehea_h_query_ehea_port(adapter->handle,
> + port->logical_port_id,
> + H_PORT_CB4,
> + H_PORT_CB4_ALL,
> + cb4);
As mpe noted as well... hret is set twice..
> +
> + if (hret != H_SUCCESS) {
> + EDEB_ERR(4, "query_ehea_port failed for cb4");
> + kfree(cb4);
> + goto get_settings_exit;
> + }
> +
> + EDEB_DMP(7, (u8*)cb4,
> + sizeof(struct hcp_query_ehea_port_cb_4), "After HCALL");
> +
> + if (netif_carrier_ok(dev)) {
> + switch(cb4->port_speed){
> + case H_PORT_SPEED_10M_H:
> + cmd->speed = SPEED_10;
> + cmd->duplex = DUPLEX_HALF;
> + break;
> + case H_PORT_SPEED_10M_F:
> + cmd->speed = SPEED_10;
> + cmd->duplex = DUPLEX_FULL;
> + break;
> + case H_PORT_SPEED_100M_H:
> + cmd->speed = SPEED_100;
> + cmd->duplex = DUPLEX_HALF;
> + break;
> + case H_PORT_SPEED_100M_F:
> + cmd->speed = SPEED_100;
> + cmd->duplex = DUPLEX_FULL;
> + break;
> + case H_PORT_SPEED_1G_F:
> + cmd->speed = SPEED_1000;
> + cmd->duplex = DUPLEX_FULL;
> + break;
> + case H_PORT_SPEED_10G_F:
> + cmd->speed = SPEED_10000;
> + cmd->duplex = DUPLEX_FULL;
> + break;
> + }
> + } else {
> + cmd->speed = -1;
> + cmd->duplex = -1;
> + }
> +
> + cmd->supported =
> + (SUPPORTED_10000baseT_Full | SUPPORTED_1000baseT_Full
> + | SUPPORTED_100baseT_Full | SUPPORTED_100baseT_Half
> + | SUPPORTED_10baseT_Full | SUPPORTED_10baseT_Half
> + | SUPPORTED_Autoneg | SUPPORTED_FIBRE);
> + cmd->advertising =
> + (ADVERTISED_10000baseT_Full | ADVERTISED_Autoneg
> + | ADVERTISED_FIBRE);
> + cmd->port = PORT_FIBRE;
> + cmd->autoneg = AUTONEG_ENABLE;
> +
> + kfree(cb4);
> + return 0;
> +
> +get_settings_exit:
> + EDEB_EX(7, "");
> + return 1;
> +}
> +
> +static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *c
md)
> +{
> + printk("set settings\n");
> + return 0;
> +}
> +
> +static void netdev_get_drvinfo(struct net_device *dev,
> + struct ethtool_drvinfo *info)
> +{
> + printk("get drvinfo\n");
> + strncpy(info->driver, EHEA_DRIVER_NAME, sizeof(info->driver) - 1);
> + strncpy(info->version, EHEA_DRIVER_VERSION, sizeof(info->version) - 1);
> +}
> +
> +static u32 netdev_get_msglevel(struct net_device *dev)
> +{
> + EDEB(7, "");
> + return (u32)ehea_trace_level;
> +}
> +
> +static void netdev_set_msglevel(struct net_device *dev, u32 value)
> +{
> + EDEB(7, "trace level set to %x", value);
> + ehea_trace_level = (int)value;
> +}
> +
> +static int netdev_nway_reset(struct net_device *dev)
> +{
> + printk("nway reset\n");
> + return 0;
> +}
> +
> +static void netdev_get_pauseparam(struct net_device *dev,
> + struct ethtool_pauseparam *pauseparam)
> +{
> + printk("get pauseparam\n");
> +}
> +
> +static int netdev_set_pauseparam(struct net_device *dev,
> + struct ethtool_pauseparam *pauseparam)
> +{
> + printk("set pauseparam\n");
> + return 0;
> +}
> +
> +static u32 netdev_get_rx_csum(struct net_device *dev)
> +{
> + printk("set rx_csum\n");
> + return 0;
> +}
> +
> +static int netdev_set_rx_csum(struct net_device *dev, u32 value)
> +{
> + printk("set rx_csum\n");
> + return 0;
> +}
> +
> +static int netdev_self_test_count(struct net_device *dev)
> +{
> + printk("self test count\n");
> + return 0;
> +}
> +
> +static void netdev_self_test(struct net_device *dev, struct ethtool_test *te
st,
> + u64 *value)
> +{
> + printk("self test\n");
> +}
> +
> +static int netdev_phys_id(struct net_device *dev, u32 value)
> +{
> + printk("physical id\n");
> + return 0;
> +}
These are yet to be done?
> +
> +static char ehea_ethtool_stats_keys[][ETH_GSTRING_LEN] = {
> + {"poll_max_processed"},
> + {"queue_stopped"},
> + {"min_swqe_avail"},
> + {"poll_receive_err"},
> + {"pkt_send"},
> + {"pkt_xmit"},
> + {"send_tasklet"},
> + {"ehea_poll"},
> + {"nwqe"},
> + {"swqe_available_0"},
> + {"rxo"},
> + {"rx64"},
> + {"rx65"},
> + {"rx128"},
> + {"rx256"},
> + {"rx512"},
> + {"rx1024"},
> + {"txo"},
> + {"tx64"},
> + {"tx65"},
> + {"tx128"},
> + {"tx256"},
> + {"tx512"},
> + {"tx1024"},
> +};
> +
> +static void netdev_get_strings(struct net_device *dev,
> + u32 stringset, u8 * data)
> +{
> + switch (stringset) {
> + case ETH_SS_TEST:
> + break;
> + case ETH_SS_STATS:
> + memcpy(data, &ehea_ethtool_stats_keys,
> + sizeof(ehea_ethtool_stats_keys));
> + }
> +}
> +
> +static int netdev_get_stats_count(struct net_device *dev)
> +{
> + return ARRAY_SIZE(ehea_ethtool_stats_keys);
> +}
> +
> +
> +static void netdev_get_ethtool_stats(struct net_device *dev,
> + struct ethtool_stats *stats, u64 *data)
> +{
> + int i = 0;
> + u64 hret = H_HARDWARE;
> + struct ehea_port *port = (struct ehea_port*)dev->priv;
> + struct ehea_adapter *adapter = port->adapter;
> + struct ehea_port_res *pr = &port->port_res[0];
> + struct port_state *p_state = &pr->p_state;
> + struct hcp_query_ehea_port_cb_6 *cb6 = NULL;
> +
> + EDEB_EN(7, "net_device=%p", dev);
> +
> + cb6 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
> + if(!cb6) {
> + EDEB_ERR(4, "No memory for cb6");
> + goto stats_exit;
> + }
> +
> + hret = ehea_h_query_ehea_port(adapter->handle,
> + port->logical_port_id,
> + H_PORT_CB6,
> + H_PORT_CB6_ALL,
> + cb6);
> +
> + if (hret != H_SUCCESS)
> + EDEB_ERR(4, "query_ehea_port failed for cb6");
> +
> + EDEB_DMP(7, (u8*)cb6,
> + sizeof(struct hcp_query_ehea_port_cb_6), "After HCALL");
> + data[i++] = p_state->poll_max_processed;
> + data[i++] = p_state->queue_stopped;
> + data[i++] = p_state->min_swqe_avail;
> + data[i++] = p_state->poll_receive_errors;
> + data[i++] = p_state->pkt_send;
> + data[i++] = p_state->pkt_xmit;
> + data[i++] = p_state->send_tasklet;
> + data[i++] = p_state->ehea_poll;
> + data[i++] = p_state->nwqe;
> + data[i++] = atomic_read(&port->port_res[0].swqe_avail);
> +
> + data[i++] = cb6->rxo;
> + data[i++] = cb6->rx64;
> + data[i++] = cb6->rx65;
> + data[i++] = cb6->rx128;
> + data[i++] = cb6->rx256;
> + data[i++] = cb6->rx512;
> + data[i++] = cb6->rx1024;
> + data[i++] = cb6->txo;
> + data[i++] = cb6->tx64;
> + data[i++] = cb6->tx65;
> + data[i++] = cb6->tx128;
> + data[i++] = cb6->tx256;
> + data[i++] = cb6->tx512;
> + data[i++] = cb6->tx1024;
> +
> + kfree(cb6);
> +stats_exit:
> + EDEB_EX(7, "");
> +}
> +
> +struct ethtool_ops ehea_ethtool_ops = {
> + .get_settings = netdev_get_settings,
> + .set_settings = netdev_set_settings,
> + .get_drvinfo = netdev_get_drvinfo,
> + .get_msglevel = netdev_get_msglevel,
> + .set_msglevel = netdev_set_msglevel,
> + .nway_reset = netdev_nway_reset,
> + .get_link = ethtool_op_get_link,
> + .get_pauseparam = netdev_get_pauseparam,
> + .set_pauseparam = netdev_set_pauseparam,
> + .get_rx_csum = netdev_get_rx_csum,
> + .set_rx_csum = netdev_set_rx_csum,
> + .get_tx_csum = ethtool_op_get_tx_csum,
> + .set_tx_csum = ethtool_op_set_tx_csum,
> + .get_sg = ethtool_op_get_sg,
> + .set_sg = ethtool_op_set_sg,
> + .get_tso = ethtool_op_get_tso,
> + .set_tso = ethtool_op_set_tso,
> + .self_test_count = netdev_self_test_count,
> + .self_test = netdev_self_test,
> + .get_strings = netdev_get_strings,
> + .phys_id = netdev_phys_id,
> + .get_stats_count = netdev_get_stats_count,
> + .get_ethtool_stats = netdev_get_ethtool_stats
> +};
> +
> +void ehea_set_ethtool_ops(struct net_device *netdev)
> +{
> + SET_ETHTOOL_OPS(netdev, &ehea_ethtool_ops);
> +}
>
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
>
I hope this helps...
Mikey
^ permalink raw reply
* Re: latest git: compile error: arch/powerpc/kernel/built-in.o
From: Michael Ellerman @ 2006-08-10 23:48 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linux-ppc
In-Reply-To: <20060810232102.GB3668@localhost>
On Fri, 2006-08-11 at 01:21 +0200, Wolfgang Pfeiffer wrote:
> On Thu, Aug 10, 2006 at 02:14:46PM -0700, Haren Myneni wrote:
> > Wolfgang Pfeiffer wrote:
> >
> > A couple of Michael's patches are needed. I am able to build with your
> > config file.
> >
> > http://ozlabs.org/pipermail/linuxppc-dev/2006-July/024271.html
> > http://ozlabs.org/pipermail/linuxppc-dev/2006-July/024272.html
>
> Yes. Works. Although I could take the patches on the pages above from the
> the corresponding messages that are still in my mail folder ... :)
>
> Strange tho' - for me at least - that these patches from about 5 weeks (!)
> ago still don't seem to have made it into the current git tree ...
Hmm, yeah. My fault for not chasing them up :)
Paul, any objection to these two?
cheers
--
Michael Ellerman
IBM OzLabs
email: michaele@au.ibm.com
stime: ellerman@au1.ibm.com
notes: Michael Ellerman/Australia/IBM
phone: +61 2 6212 1183 (tie line 70 21183)
We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person
^ permalink raw reply
* Realtime preemption patch on PPC
From: Ben Weintraub @ 2006-08-10 23:04 UTC (permalink / raw)
To: linuxppc-embedded
Howdy,
I'm wondering if anyone has had success getting Ingo Molnar's realtime
preemption patch (the one here:
http://people.redhat.com/mingo/realtime-preempt/ ) working on the ppc
arch.
I'm working with patch-2.6.17-rt8 (the latest) and linux-2.6.17. The
realtime-preempt patch seems to include the generic timeofday patch, but
with no support for the ppc arch, only powerpc, so I've hacked in
support for ppc by basically replicating the powerpc arch-specific stuff
found here:
http://sr71.net/~jstultz/tod/archive/linux-2.6.17-rc3_timekeeping_C2/broken-out/linux-2.6.17-rc3_timeofday-arch-ppc_C2.patch
I can attach my patch if anyone would like, but for all I know it could
be wildly inaccurate.
Anyhow, when I boot on an MPC8555 with my hack, I get an endless stream
of:
BUG: sleeping function called from invalid context init(1) at
arch/powerpc/math-emu/math.c:226
in_atomic():0 [00000000], irqs_disabled():1
Call Trace:
[A0BB3E90] [A000934C] show_stack+0x48/0x194 (unreliable)
[A0BB3EC0] [A001B7DC] __might_sleep+0xe8/0xf4
[A0BB3EE0] [A00136C0] do_mathemu+0x30/0x8c8
[A0BB3F00] [A00036AC] program_check_exception+0x1ac/0x514
[A0BB3F40] [A0002A08] ret_from_except_full+0x0/0x4c
Line 226 in arch/powerpc/math-emu/math.c is part of the do_mathemu()
function, and contains a call to get_user(), which calls
__might_sleep(), causing this problem.
I did find this message in the LKML archives describing a very similar
problem:
http://lkml.org/lkml/2006/2/23/312
And so tried putting a call to local_irq_enable() before the call to
do_mathemu() in program_check_excpetion(), but this causes a hard lockup
with no messages printed when I try to bring up my network interface. I
assume this means I've done something Very Bad with interrupts by adding
in local_irq_enable() at the wrong spot. I also tried adding it at the
exact same spot as the patch given by Paul in his reply, but in this
case I still get the endless stream of BUG messages.
Can anyone offer some guidance or advice?
Thanks so much,
Ben
^ permalink raw reply
* Re: latest git: compile error: arch/powerpc/kernel/built-in.o
From: Wolfgang Pfeiffer @ 2006-08-10 23:21 UTC (permalink / raw)
To: Haren Myneni; +Cc: linux-ppc, ellerman
In-Reply-To: <44DBA1C6.2020902@us.ibm.com>
On Thu, Aug 10, 2006 at 02:14:46PM -0700, Haren Myneni wrote:
> Wolfgang Pfeiffer wrote:
>
> A couple of Michael's patches are needed. I am able to build with your
> config file.
>
> http://ozlabs.org/pipermail/linuxppc-dev/2006-July/024271.html
> http://ozlabs.org/pipermail/linuxppc-dev/2006-July/024272.html
Yes. Works. Although I could take the patches on the pages above from the
the corresponding messages that are still in my mail folder ... :)
Strange tho' - for me at least - that these patches from about 5 weeks (!)
ago still don't seem to have made it into the current git tree ...
>
> Thanks
> Haren
Ditto: Thanks. To Michael Ellerman, too :)
Best Regards
Wolfgang
>
> >Hi All
> >
> >I'm trying to compile a fresh git kernel, with latest sources pulled today,
> >Aug. 10. To no avail so far.
[ ... ]
--
Wolfgang Pfeiffer: /ICQ: 286585973/ + + + /AIM: crashinglinux/
http://profiles.yahoo.com/wolfgangpfeiffer
Key ID: E3037113
http://keyserver.mine.nu/pks/lookup?search=0xE3037113&fingerprint=on
^ permalink raw reply
* Re: Which is better for Wireless Network Support, 2.6 or 2.4?
From: Lee Revell @ 2006-08-10 22:04 UTC (permalink / raw)
To: wei.li4; +Cc: linuxppc-embedded
In-Reply-To: <20060810132251.ycxgkqik5csw0gc0@webmail.mcgill.ca>
On Thu, 2006-08-10 at 13:22 -0400, wei.li4@elf.mcgill.ca wrote:
> Hi All,
>
> I am working on wireless data application via MPC875 host USB, is there
> any difference to use Linux 2.6.x or Linux 2.4.x? Is it Linux 2.6 more
> like RTOS? Thanks.
>
Yes, absolutely. Recent Linux 2.6 kernels (since 2.6.14 or so) have
much better RT performance if PREEMPT is enabled than any 2.4 kernel.
Lee
^ permalink raw reply
* Re: latest git: compile error: arch/powerpc/kernel/built-in.o
From: Haren Myneni @ 2006-08-10 21:14 UTC (permalink / raw)
To: Wolfgang Pfeiffer; +Cc: linux-ppc, ellerman
In-Reply-To: <20060810181154.GA3668@localhost>
Wolfgang Pfeiffer wrote:
A couple of Michael's patches are needed. I am able to build with your
config file.
http://ozlabs.org/pipermail/linuxppc-dev/2006-July/024271.html
http://ozlabs.org/pipermail/linuxppc-dev/2006-July/024272.html
Thanks
Haren
>Hi All
>
>I'm trying to compile a fresh git kernel, with latest sources pulled today,
>Aug. 10. To no avail so far.
>
>OS is Debian/unstable, last time I upgraded the system as far as the
>dependencies allowed doing that was yesterday, Aug. 10.
>
>---------------------
>$ cat /proc/cpuinfo
>processor : 0
>cpu : 7447A, altivec supported
>clock : 833.333000MHz
>revision : 0.5 (pvr 8003 0105)
>bogomips : 16.57
>timebase : 8320000
>platform : PowerMac
>machine : PowerBook5,8
>motherboard : PowerBook5,8 MacRISC3 Power Macintosh
>detected as : 287 (PowerBook G4 15")
>pmac flags : 00000019
>L2 cache : 512K unified
>pmac-generation : NewWorld
>-----------------------------
>
>Here's the config I used:
>
>http://wolfgangpfeiffer.com/config.060810.txt
>
>The compile messages:
>
>--------------------------------
>time MAKEFLAGS="CC=gcc-4.1" fakeroot make-kpkg --append-to-version=-060810 kernel_image
>
>results in [excerpts]:
>
> CC lib/sha1.o
> CC lib/string.o
> CC lib/vsprintf.o
> AR lib/lib.a
> GEN .version
> CHK include/linux/compile.h
> UPD include/linux/compile.h
> CC init/version.o
> LD init/built-in.o
> LD .tmp_vmlinux1
>arch/powerpc/kernel/built-in.o: In function `__restore_cpu_setup':
>(.text+0xcd34): undefined reference to `kexec_sr_activated'
>arch/powerpc/kernel/built-in.o: In function `__restore_cpu_setup':
>(.text+0xcd44): undefined reference to `crash_kexec_secondary'
>arch/powerpc/kernel/built-in.o: In function `early_init_devtree':
>(.init.text+0x1cdc): undefined reference to `reserve_crashkernel'
>arch/powerpc/kernel/built-in.o: In function `early_init_devtree':
>(.init.text+0x1e1c): undefined reference to `overlaps_crashkernel'
>make[1]: *** [.tmp_vmlinux1] Error 1
>make[1]: Leaving directory `/home/shorty/kernel-factory/git.08102006/linux-2.6'
>make: *** [debian/stamp-build-kernel] Error 2
>
>real 9m39.089s
>user 8m21.904s
>sys 0m59.167s
>
>------------------------------------------------------------
>
>and with gcc-4.0 the same:
>
>time MAKEFLAGS="CC=gcc-4.0" fakeroot make-kpkg --append-to-version=-060810 kernel_image
>
>results in [excerpts]:
>
> CC lib/vsprintf.o
> AR lib/lib.a
> GEN .version
> CHK include/linux/compile.h
> UPD include/linux/compile.h
> CC init/version.o
> LD init/built-in.o
> LD .tmp_vmlinux1
>arch/powerpc/kernel/built-in.o: In function `__restore_cpu_setup':
>(.text+0xcccc): undefined reference to `kexec_sr_activated'
>arch/powerpc/kernel/built-in.o: In function `__restore_cpu_setup':
>(.text+0xccdc): undefined reference to `crash_kexec_secondary'
>arch/powerpc/kernel/built-in.o: In function `early_init_devtree':
>(.init.text+0x15d0): undefined reference to `reserve_crashkernel'
>arch/powerpc/kernel/built-in.o: In function `early_init_devtree':
>(.init.text+0x1710): undefined reference to `overlaps_crashkernel'
>make[1]: *** [.tmp_vmlinux1] Error 1
>make[1]: Leaving directory `/home/shorty/kernel-factory/git.08102006/linux-2.6'
>make: *** [debian/stamp-build-kernel] Error 2
>
>--------------------------------------
>
>Please let me know if you need more details.
>
>Thanks in anticipation
>
>Best Regards
>Wolfgang Pfeiffer
>
>
>
^ permalink raw reply
* kernel panic: BUG in cascade at kernel/timer.c
From: Bizhan Gholikhamseh (bgholikh) @ 2006-08-10 21:12 UTC (permalink / raw)
To: linuxppc-embedded
[-- Attachment #1: Type: text/plain, Size: 1535 bytes --]
Hi All,
We have developed our own custom board based on MPC8541 board running
linux 2.6.11
During stress testing the system we get following kernel panic which
related to timer cascase.
Any hints greatly apprieciated. Many thanks in advance:
kernel BUG in cascade at kernel/timer.c:416!
Oops: Exception in kernel mode, sig: 5 [#1]
PREEMPT
NIP: C0023AB4 LR: C0023CC8 SP: C02DDDF0 REGS: c02ddd40 TRAP: 0700
Tainted: P
MSR: 00021200 EE: 0 PR: 0 FP: 0 ME: 1 IR/DR: 00
TASK = c02bb730[0] 'swapper' THREAD: c02dc000
Last syscall: 120
File timer.c line 416 :
401 static int cascade(tvec_base_t *base, tvec_t *tv, int index)
402 {
403 /* cascade all the timers from tv up one level */
404 struct list_head *head, *curr;
405
406 head = tv->vec + index;
407 curr = head->next;
408 /*
409 * We are removing _all_ timers from the list, so we
don't have
to
410 * detach them individually, just clear the list
afterwards.
411 */
412 while (curr != head) {
413 struct timer_list *tmp;
414
415 tmp = list_entry(curr, struct timer_list,
entry);
416 BUG_ON(tmp->base != base);
417 curr = curr->next;
418 internal_add_timer(base, tmp);
419 }
420 INIT_LIST_HEAD(head);
421
422 return index;
Regards,
Bizhan
[-- Attachment #2: Type: text/html, Size: 4369 bytes --]
^ permalink raw reply
* RE: Debugging with no serial port
From: Ben Warren @ 2006-08-10 20:53 UTC (permalink / raw)
To: Martin, Tim; +Cc: linuxppc-embedded
In-Reply-To: <821B2170E9E7F04FA38DF7EC21DE487105FD14A0@VCAEXCH01.hq.corp.viasat.com>
Martin,
On Thu, 2006-08-10 at 13:12 -0700, Martin, Tim wrote:
>
> I tried this as well and have the same GDB synchronization problem e.g.
>
> break log_stuff
> commands
> silent
> if (variable_logging_enabled)
> printf "(%d,%d)\n",stuff1_variable,stuff2_variable
> end
> cont
> end
>
That's too bad. I wonder if you could run gdb from expect or some other
auto-scripting language and have it issue the 'cont' once all data is
printed (Have your code spit out a special 'end of data' delimiter).
Just a thought - no idea if it would work.
I'm not 100% certain how BDI-2000/gdb works, but I guess the gdb server
is running on the box, in which case you probably don't have much
control over how it works, and thus can't control if the output stream
is buffered or not. My BDI-2000 book doesn't have much on configuring
the gdb part.
Anyway, sorry for rambling.
regards,
Ben
^ permalink raw reply
* RE: Debugging with no serial port
From: Martin, Tim @ 2006-08-10 20:12 UTC (permalink / raw)
To: bwarren; +Cc: linuxppc-embedded
Ben,
> How about something a bit simpler like running gdb within a
'script' context,
> which will log your session to a file. Get gdb to print the variables
to the screen
> (using 'print' or whatever), wrap your data with easily searchable
characters=20
> (eg. ***data1 data2 data3***), then filter your data from the script
file with sed/awk
> or perl scripts?
=09
I tried this as well and have the same GDB synchronization problem e.g.
break log_stuff
commands
silent
if (variable_logging_enabled)
printf "(%d,%d)\n",stuff1_variable,stuff2_variable
end
cont
end
The printf's don't complete before the cont happens. Sounds like maybe
this is a GDB problem...
Tim
=09
^ permalink raw reply
* Re: Debugging with no serial port
From: Ben Warren @ 2006-08-10 19:27 UTC (permalink / raw)
To: Martin, Tim; +Cc: linuxppc-embedded
In-Reply-To: <821B2170E9E7F04FA38DF7EC21DE487105FD10D3@VCAEXCH01.hq.corp.viasat.com>
[-- Attachment #1: Type: text/plain, Size: 2322 bytes --]
Tim,
How about something a bit simpler like running gdb within a 'script'
context, which will log your session to a file. Get gdb to print the
variables to the screen (using 'print' or whatever), wrap your data with
easily searchable characters (eg. ***data1 data2 data3***), then filter
your data from the script file with sed/awk or perl scripts?
A bit brute force, but bound to work.
regards,
Ben
On Thu, 2006-08-10 at 10:14 -0700, Martin, Tim wrote:
> This may be more of a question for GDB folks...but I'll post it here
> because it relates to embedded systems as well.
>
> I'm trying to validate some signal processing software on an embedded
> Virtex4 PowerPC 405. Basically, the validation consists of calling
> functions and looking at their outputs. Over time, there are several
> thousand numbers to look at, so manually looking at each number at a
> break point would be very time consuming (to put it mildly).
>
> The normal way I would go about doing this is to print out the data
> (e.g. to a serial port) and post-process the data somewhere else. But
> on this particular target, I don't have a serial port. So I thought
> about using GDB's breakpoint command list feature. When the software
> has data it wants to print out, it calls a function "log_stuff". I
> then set a breakpoint and command list in the "log_stuff" function,
> which writes out the variables I'm interested in checking out to a
> file named outputfile.bin. E.g. the following command file does this:
>
> break log_stuff
> commands
> silent
> if (variable_logging_enabled)
> append value outputfile.bin stuff1_variable
> append value outputfile.bin stuff2_variable
> end
> cont
> end
>
> The problem I have with this approach is that GDB doesn't finish
> writing out everything before it continues executing the program, so a
> backlog develops. So my first question would be, is there some GDB
> "flush" like command I could run before the cont statement?
>
> Second question would be - is there an easier way to accomplish what
> I'm trying to do, which is basically emulate a serial port with GDB.
>
> Tim
>
>
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
[-- Attachment #2: Type: text/html, Size: 4628 bytes --]
^ permalink raw reply
* Re: Debugging with no serial port
From: Brian Waite @ 2006-08-10 19:13 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <821B2170E9E7F04FA38DF7EC21DE487105FD1342@VCAEXCH01.hq.corp.viasat.com>
On Thursday 10 August 2006 15:00, Martin, Tim wrote:
> >> Second question would be - is there an easier way to accomplish what
> >> I'm trying to do, which is basically emulate a serial port with GDB.
> >
> > Use NetConsole or remotey log it with syslog...
>
> I guess I wasn't clear in the problem statement - this target doesn't
> have a serial port, an ethernet port, or a file system. So I can't log
> over Ethernet or log by writing to a file. I'm fairly restricted to
> getting data out of the system using GDB controlling a hardware JTAG
> debugger (think BDI2000).
I don't know GDB internals so I cannot answer the specific question relating
to synchronous writes via GDB.
But...
How much data are we talking and is there some area of private memory to stash
the logged data in and use the JTAG adapter to fetch the memory blocks and
write to a local file for post processing? I've done this in places where I
am doing kernbel bringup without a serial port. Your other option is use a
few IO pins (if available) and make a bit banging serial interface with some
extrnal components.
Thanks
Brian
^ permalink raw reply
* RE: Debugging with no serial port
From: Martin, Tim @ 2006-08-10 19:00 UTC (permalink / raw)
To: Frank, linuxppc-embedded
=20
>> Second question would be - is there an easier way to accomplish what=20
>> I'm trying to do, which is basically emulate a serial port with GDB.
>=20
> Use NetConsole or remotey log it with syslog...
>=20
I guess I wasn't clear in the problem statement - this target doesn't
have a serial port, an ethernet port, or a file system. So I can't log
over Ethernet or log by writing to a file. I'm fairly restricted to
getting data out of the system using GDB controlling a hardware JTAG
debugger (think BDI2000).
Tim
^ permalink raw reply
* Re: [RFC] consolidated libdt proposal
From: Mark A. Greer @ 2006-08-10 18:55 UTC (permalink / raw)
To: Milton Miller
Cc: hollisb, pantelis, linuxppc-embedded, linuxppc-dev, xen-ppc-devel
In-Reply-To: <11155228690643c98691.1714636915.miltonm@bga.com>
On Thu, Aug 10, 2006 at 11:51:30AM -0500, Milton Miller wrote:
> On Tue Aug 8 2006 01:04:08 PM CDT, Mark A. Greer wrote:
> > If we're going to allow cmdline editing in the bootwrapper, we would
> > need to extend the size of a property. We've never really talked about
> > cmdline editing in the powerpc branch but I assume that its a good
> > thing(tm). I know I would like to have it so, IMHO, I think we should
> > add it (and therefore require extending a property).
>
> We already have replace the command line merged (it's why my patches
> don't apply).
That's different. What you're talking about is the code that supports
sticking a cmdline in a separate section of the zImage and using it.
What I'm talking about is editing the cmdline at runtime (as in what
used to happen in arch/ppc).
Not sure if we need all of these options but that's what I was talking
about.
Mark
^ permalink raw reply
* latest git: compile error: arch/powerpc/kernel/built-in.o
From: Wolfgang Pfeiffer @ 2006-08-10 18:11 UTC (permalink / raw)
To: linux-ppc
Hi All
I'm trying to compile a fresh git kernel, with latest sources pulled today,
Aug. 10. To no avail so far.
OS is Debian/unstable, last time I upgraded the system as far as the
dependencies allowed doing that was yesterday, Aug. 10.
---------------------
$ cat /proc/cpuinfo
processor : 0
cpu : 7447A, altivec supported
clock : 833.333000MHz
revision : 0.5 (pvr 8003 0105)
bogomips : 16.57
timebase : 8320000
platform : PowerMac
machine : PowerBook5,8
motherboard : PowerBook5,8 MacRISC3 Power Macintosh
detected as : 287 (PowerBook G4 15")
pmac flags : 00000019
L2 cache : 512K unified
pmac-generation : NewWorld
-----------------------------
Here's the config I used:
http://wolfgangpfeiffer.com/config.060810.txt
The compile messages:
--------------------------------
time MAKEFLAGS="CC=gcc-4.1" fakeroot make-kpkg --append-to-version=-060810 kernel_image
results in [excerpts]:
CC lib/sha1.o
CC lib/string.o
CC lib/vsprintf.o
AR lib/lib.a
GEN .version
CHK include/linux/compile.h
UPD include/linux/compile.h
CC init/version.o
LD init/built-in.o
LD .tmp_vmlinux1
arch/powerpc/kernel/built-in.o: In function `__restore_cpu_setup':
(.text+0xcd34): undefined reference to `kexec_sr_activated'
arch/powerpc/kernel/built-in.o: In function `__restore_cpu_setup':
(.text+0xcd44): undefined reference to `crash_kexec_secondary'
arch/powerpc/kernel/built-in.o: In function `early_init_devtree':
(.init.text+0x1cdc): undefined reference to `reserve_crashkernel'
arch/powerpc/kernel/built-in.o: In function `early_init_devtree':
(.init.text+0x1e1c): undefined reference to `overlaps_crashkernel'
make[1]: *** [.tmp_vmlinux1] Error 1
make[1]: Leaving directory `/home/shorty/kernel-factory/git.08102006/linux-2.6'
make: *** [debian/stamp-build-kernel] Error 2
real 9m39.089s
user 8m21.904s
sys 0m59.167s
------------------------------------------------------------
and with gcc-4.0 the same:
time MAKEFLAGS="CC=gcc-4.0" fakeroot make-kpkg --append-to-version=-060810 kernel_image
results in [excerpts]:
CC lib/vsprintf.o
AR lib/lib.a
GEN .version
CHK include/linux/compile.h
UPD include/linux/compile.h
CC init/version.o
LD init/built-in.o
LD .tmp_vmlinux1
arch/powerpc/kernel/built-in.o: In function `__restore_cpu_setup':
(.text+0xcccc): undefined reference to `kexec_sr_activated'
arch/powerpc/kernel/built-in.o: In function `__restore_cpu_setup':
(.text+0xccdc): undefined reference to `crash_kexec_secondary'
arch/powerpc/kernel/built-in.o: In function `early_init_devtree':
(.init.text+0x15d0): undefined reference to `reserve_crashkernel'
arch/powerpc/kernel/built-in.o: In function `early_init_devtree':
(.init.text+0x1710): undefined reference to `overlaps_crashkernel'
make[1]: *** [.tmp_vmlinux1] Error 1
make[1]: Leaving directory `/home/shorty/kernel-factory/git.08102006/linux-2.6'
make: *** [debian/stamp-build-kernel] Error 2
--------------------------------------
Please let me know if you need more details.
Thanks in anticipation
Best Regards
Wolfgang Pfeiffer
--
Wolfgang Pfeiffer: /ICQ: 286585973/ + + + /AIM: crashinglinux/
http://profiles.yahoo.com/wolfgangpfeiffer
Key ID: E3037113
http://keyserver.mine.nu/pks/lookup?search=0xE3037113&fingerprint=on
^ permalink raw reply
* Compatibility Problem between linux-2.4.25 and RedBoot
From: wei.li4 @ 2006-08-10 18:02 UTC (permalink / raw)
To: linuxppc-embedded
Hi all,
Since my evaluation board based on MPC875 is pre-installed RedBoot
Loader and Linux with this kit can be loaded and execute, but I want to
try public powerpc linux, which can be loaded, but not execute. Dose
any one know how to change it so that it is compatible with RedBoot? I
checked the definition of struct bd_info{} is different, is it the
shared struct by bootloader and Linux? How dose loader work with linux?
Thanks.
Wei
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox