patch-2.4.23 linux-2.4.23/arch/ia64/sn/io/sn2/shub_intr.c
Next file: linux-2.4.23/arch/ia64/sn/io/sn2/shuberror.c
Previous file: linux-2.4.23/arch/ia64/sn/io/sn2/shub.c
Back to the patch index
Back to the overall index
- Lines: 98
- Date:
2003-11-28 10:26:19.000000000 -0800
- Orig file:
linux-2.4.22/arch/ia64/sn/io/sn2/shub_intr.c
- Orig date:
2003-08-25 04:44:39.000000000 -0700
diff -urN linux-2.4.22/arch/ia64/sn/io/sn2/shub_intr.c linux-2.4.23/arch/ia64/sn/io/sn2/shub_intr.c
@@ -27,6 +27,9 @@
#include <asm/sn/klconfig.h>
#include <asm/sn/sn2/shub_mmr.h>
#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/pci/pcibr.h>
+#include <asm/sn/pci/pcibr_private.h>
+#include <asm/sn/pci/bridge.h>
/* ARGSUSED */
void
@@ -37,11 +40,15 @@
xwidgetnum_t
hub_widget_id(nasid_t nasid)
{
- hubii_wcr_t ii_wcr; /* the control status register */
-
- ii_wcr.wcr_reg_value = REMOTE_HUB_L(nasid,IIO_WCR);
-
- return ii_wcr.wcr_fields_s.wcr_widget_id;
+
+ if (!(nasid & 1)) {
+ hubii_wcr_t ii_wcr; /* the control status register */
+ ii_wcr.wcr_reg_value = REMOTE_HUB_L(nasid,IIO_WCR);
+ return ii_wcr.wcr_fields_s.wcr_widget_id;
+ } else {
+ /* ICE does not have widget id. */
+ return(-1);
+ }
}
static hub_intr_t
@@ -79,7 +86,7 @@
xtalk_addr = SH_II_INT0 | ((unsigned long)nasid << 36) | (1UL << 47);
}
- intr_hdl = snia_kmem_alloc_node(sizeof(struct hub_intr_s), KM_NOSLEEP, cnode);
+ intr_hdl = snia_kmem_alloc_node(sizeof(struct hub_intr_s), cnode);
ASSERT_ALWAYS(intr_hdl);
xtalk_info = &intr_hdl->i_xtalk_info;
@@ -188,3 +195,57 @@
ASSERT(rv == 0);
intr_hdl->i_flags &= ~HUB_INTR_IS_CONNECTED;
}
+
+/*
+ * Redirect an interrupt to another cpu.
+ */
+
+void
+sn_shub_redirect_intr(pcibr_intr_t intr, unsigned long cpu) {
+ unsigned long bit;
+ int cpuphys, slice;
+ nasid_t nasid;
+ unsigned long xtalk_addr;
+ bridge_t *bridge = intr->bi_soft->bs_base;
+ picreg_t int_enable;
+ picreg_t host_addr;
+ int irq;
+
+ cpuphys = cpu_physical_id(cpu);
+ slice = cpu_physical_id_to_slice(cpuphys);
+ nasid = cpu_physical_id_to_nasid(cpuphys);
+
+ if (slice) {
+ xtalk_addr = SH_II_INT1 | ((unsigned long)nasid << 36) | (1UL << 47);
+ } else {
+ xtalk_addr = SH_II_INT0 | ((unsigned long)nasid << 36) | (1UL << 47);
+ }
+
+ for (bit = 0; bit < 8; bit++) {
+ if (intr->bi_ibits & (1 << bit) ) {
+ /* Disable interrupts. */
+ int_enable = bridge->p_int_enable_64;
+ int_enable &= ~bit;
+ bridge->p_int_enable_64 = int_enable;
+ /* Reset Host address (Interrupt destination) */
+ host_addr = bridge->p_int_addr_64[bit];
+ host_addr &= ~((1UL << 48) - 1);
+ host_addr |= xtalk_addr;
+ bridge->p_int_addr_64[bit] = host_addr;
+ /* Enable interrupt */
+ int_enable |= bit;
+ bridge->p_int_enable_64 = int_enable;
+ /* Force an interrupt, just in case. */
+ bridge->b_force_pin[bit].intr = 1;
+ }
+ }
+ irq = intr->bi_irq;
+ if (pdacpu(cpu).sn_first_irq == 0 || pdacpu(cpu).sn_first_irq > irq) {
+ pdacpu(cpu).sn_first_irq = irq;
+ }
+ if (pdacpu(cpu).sn_last_irq < irq) {
+ pdacpu(cpu).sn_last_irq = irq;
+ }
+ intr->bi_cpu = (int)cpu;
+}
+
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)