patch-2.4.0-test3 linux/arch/sparc64/kernel/irq.c
Next file: linux/arch/sparc64/kernel/pci_sabre.c
Previous file: linux/arch/sparc64/kernel/binfmt_aout32.c
Back to the patch index
Back to the overall index
- Lines: 143
- Date:
Wed Jul 5 22:15:25 2000
- Orig file:
v2.4.0-test2/linux/arch/sparc64/kernel/irq.c
- Orig date:
Tue May 23 15:31:34 2000
diff -u --recursive --new-file v2.4.0-test2/linux/arch/sparc64/kernel/irq.c linux/arch/sparc64/kernel/irq.c
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.87 2000/05/09 17:40:13 davem Exp $
+/* $Id: irq.c,v 1.89 2000/06/30 10:18:38 davem Exp $
* irq.c: UltraSparc IRQ handling/init/registry.
*
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -62,6 +62,19 @@
#define irq_work(__cpu, __pil) &(cpu_data[(__cpu)].irq_worklists[(__pil)])
#endif
+#ifdef CONFIG_PCI
+/* This is a table of physical addresses used to deal with SA_DMA_SYNC.
+ * It is used for PCI only to synchronize DMA transfers with IRQ delivery
+ * for devices behind busses other than APB on Sabre systems.
+ *
+ * Currently these physical addresses are just config space accesses
+ * to the command register for that device.
+ */
+unsigned long pci_dma_wsync;
+unsigned long dma_sync_reg_table[256];
+unsigned char dma_sync_reg_table_entry = 0;
+#endif
+
/* This is based upon code in the 32-bit Sparc kernel written mostly by
* David Redman (djhr@tadpole.co.uk).
*/
@@ -280,8 +293,6 @@
/*
* Check wether we _should_ use DMA Write Sync
* (for devices behind bridges behind APB).
- *
- * XXX: Not implemented, yet.
*/
if (bucket->flags & IBF_DMA_SYNC)
irqflags |= SA_DMA_SYNC;
@@ -541,8 +552,8 @@
* lives in the brlock table for cache reasons.
*/
#ifndef CONFIG_SMP
-unsigned int local_irq_count;
-unsigned int local_bh_count;
+unsigned int __local_irq_count;
+unsigned int __local_bh_count;
#else
/* Who has global_irq_lock. */
@@ -594,14 +605,14 @@
spinlock_t *lock;
if (!irqs_running() &&
- (local_bh_count || !spin_is_locked(&global_bh_lock)))
+ (local_bh_count(smp_processor_id()) || !spin_is_locked(&global_bh_lock)))
break;
br_write_unlock(BR_GLOBALIRQ_LOCK);
lock = &__br_write_locks[BR_GLOBALIRQ_LOCK].lock;
while (irqs_running() ||
spin_is_locked(lock) ||
- (!local_bh_count && spin_is_locked(&global_bh_lock))) {
+ (!local_bh_count(smp_processor_id()) && spin_is_locked(&global_bh_lock))) {
if (!--count) {
show("wait_on_irq");
count = (~0 >> 1);
@@ -624,7 +635,7 @@
if(flags == 0) {
int cpu = smp_processor_id();
__cli();
- if (! local_irq_count)
+ if (! local_irq_count(cpu))
get_irqlock(cpu);
}
}
@@ -633,7 +644,7 @@
{
int cpu = smp_processor_id();
- if (! local_irq_count)
+ if (! local_irq_count(cpu))
release_irqlock(cpu);
__sti();
}
@@ -645,7 +656,7 @@
__save_flags(flags);
local_enabled = ((flags == 0) ? 1 : 0);
retval = 2 + local_enabled;
- if (! local_irq_count) {
+ if (! local_irq_count(smp_processor_id())) {
if (local_enabled)
retval = 1;
if (global_irq_holder == (unsigned char) smp_processor_id())
@@ -719,14 +730,14 @@
/* 'cpu' is the MID (ie. UPAID), calculate the MID
* of our buddy.
*/
- if(should_forward != 0) {
+ if (should_forward != 0) {
buddy = cpu_number_map(cpu) + 1;
if (buddy >= NR_CPUS ||
(buddy = cpu_logical_map(buddy)) == -1)
buddy = cpu_logical_map(0);
/* Voo-doo programming. */
- if(cpu_data[buddy].idle_volume < FORWARD_VOLUME)
+ if (cpu_data[buddy].idle_volume < FORWARD_VOLUME)
should_forward = 0;
buddy <<= 26;
}
@@ -752,25 +763,29 @@
#else
bp = __bucket(xchg32(irq_work(cpu, irq), 0));
#endif
- for( ; bp != NULL; bp = nbp) {
+ for ( ; bp != NULL; bp = nbp) {
unsigned char flags = bp->flags;
nbp = __bucket(bp->irq_chain);
- if((flags & IBF_ACTIVE) != 0) {
- if((flags & IBF_MULTI) == 0) {
+ if ((flags & IBF_ACTIVE) != 0) {
+ if ((flags & IBF_DMA_SYNC) != 0) {
+ upa_readl(dma_sync_reg_table[bp->synctab_ent]);
+ upa_readq(pci_dma_wsync);
+ }
+ if ((flags & IBF_MULTI) == 0) {
struct irqaction *ap = bp->irq_info;
ap->handler(__irq(bp), ap->dev_id, regs);
} else {
void **vector = (void **)bp->irq_info;
int ent;
- for(ent = 0; ent < 4; ent++) {
+ for (ent = 0; ent < 4; ent++) {
struct irqaction *ap = vector[ent];
- if(ap != NULL)
+ if (ap != NULL)
ap->handler(__irq(bp), ap->dev_id, regs);
}
}
/* Only the dummy bucket lacks IMAP/ICLR. */
- if(bp->pil != 0) {
+ if (bp->pil != 0) {
#ifdef CONFIG_SMP
/* Ok, here is what is going on:
* 1) Retargeting IRQs on Starfire is very
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)