module_t *module_add_node(moduleid_t id, cnodeid_t n) { module_t *m; int i; DPRINTF("module_add_node: id=%x node=%d\n", id, n); if ((m = module_lookup(id)) == 0) { #ifndef CONFIG_IA64_SGI_IO m = kmem_zalloc_node(sizeof (module_t), KM_NOSLEEP, n); #else m = kmalloc(sizeof (module_t), GFP_KERNEL); memset(m, 0 , sizeof(module_t)); printk("Module nodecnt = %d\n", m->nodecnt); #endif ASSERT_ALWAYS(m); DPRINTF("module_add_node: m=0x%p\n", m); m->id = id; spin_lock_init(&m->lock); init_MUTEX_LOCKED(&m->thdcnt); printk("Set elsc to 0x%p on node %d\n", &m->elsc, get_nasid()); set_elsc(&m->elsc); elsc_init(&m->elsc, COMPACT_TO_NASID_NODEID(n)); spin_lock_init(&m->elsclock); /* Insert in sorted order by module number */ for (i = nummodules; i > 0 && modules[i - 1]->id > id; i--) modules[i] = modules[i - 1]; modules[i] = m; nummodules++; } m->nodes[m->nodecnt++] = n; printk("module_add_node: module %x now has %d nodes\n", id, m->nodecnt); DPRINTF("module_add_node: module %x now has %d nodes\n", id, m->nodecnt); return m; }
module_t *module_add_node(moduleid_t id, cnodeid_t n) { module_t *m; int i; char buffer[16]; #ifdef __ia64 memset(buffer, 0, 16); format_module_id(buffer, id, MODULE_FORMAT_BRIEF); DPRINTF("module_add_node: id=%s node=%d\n", buffer, n); #endif if ((m = module_lookup(id)) == 0) { #ifdef LATER m = kmem_zalloc_node(sizeof (module_t), KM_NOSLEEP, n); #else m = kmalloc(sizeof (module_t), GFP_KERNEL); memset(m, 0 , sizeof(module_t)); #endif ASSERT_ALWAYS(m); m->id = id; spin_lock_init(&m->lock); mutex_init_locked(&m->thdcnt); // set_elsc(&m->elsc); elsc_init(&m->elsc, COMPACT_TO_NASID_NODEID(n)); spin_lock_init(&m->elsclock); /* Insert in sorted order by module number */ for (i = nummodules; i > 0 && modules[i - 1]->id > id; i--) modules[i] = modules[i - 1]; modules[i] = m; nummodules++; } m->nodes[m->nodecnt++] = n; DPRINTF("module_add_node: module %s now has %d nodes\n", buffer, m->nodecnt); return m; }
void hub_error_init(cnodeid_t cnode) { nasid_t nasid; nasid = cnodeid_to_nasid(cnode); hub_error_clear(nasid); #ifdef ajm if (cnode == 0) { /* * Allocate log for storing the node specific error info */ for (i = 0; i < numnodes; i++) { kl_error_log[i] = kmem_zalloc_node(sizeof(sn0_error_log_t), KM_NOSLEEP, i); hub_err_count[i] = kmem_zalloc_node(sizeof(hub_errcnt_t), VM_DIRECT | KM_NOSLEEP, i); ASSERT_ALWAYS(kl_error_log[i] && hub_err_count[i]); } } /* * Assumption: There will be only one cpu who will initialize * a hub. we need to setup the ii and each pi error interrupts. * The SN1 hub (bedrock) has two PI, one for up to two processors. */ if (cpuid_to_cnodeid(smp_processor_id()) == cnode) { int generic_intr_mask = PI_ERR_GENERIC; /* These interrupts are sent to only 1 CPU per NODE */ ASSERT_ALWAYS(kl_error_log[cnode]); ASSERT_ALWAYS(hub_err_count[cnode]); MD_ERR_LOG_INIT(kl_error_log[cnode]); /* One for each CPU */ recover_error_init(RECOVER_ERROR_TABLE(cnode, 0)); recover_error_init(RECOVER_ERROR_TABLE(cnode, 1)); recover_error_init(RECOVER_ERROR_TABLE(cnode, 2)); recover_error_init(RECOVER_ERROR_TABLE(cnode, 3)); /* * Setup error intr masks. */ for(sn=0; sn<NUM_SUBNODES; sn++) { int cpuA_present = REMOTE_HUB_PI_L(nasid, sn, PI_CPU_ENABLE_A); int cpuB_present = REMOTE_HUB_PI_L(nasid, sn, PI_CPU_ENABLE_B); if (cpuA_present) { if (cpuB_present) { /* A && B */ REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_A, (PI_FATAL_ERR_CPU_B | PI_MISC_ERR_CPU_A|generic_intr_mask)); REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_B, (PI_FATAL_ERR_CPU_A | PI_MISC_ERR_CPU_B)); } else { /* A && !B */ REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_A, (PI_FATAL_ERR_CPU_A | PI_MISC_ERR_CPU_A|generic_intr_mask)); } generic_intr_mask = 0; } else { if (cpuB_present) { /* !A && B */ REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_B, (PI_FATAL_ERR_CPU_B | PI_MISC_ERR_CPU_B|generic_intr_mask)); generic_intr_mask = 0; } else { /* !A && !B */ /* nothing to set up */ } } } /* * Turn off UNCAC_UNCORR interrupt in the masks. Anyone interested * in these errors will peek at the int pend register to see if its * set. */ for(sn=0; sn<NUM_SUBNODES; sn++) { misc = REMOTE_HUB_PI_L(nasid, sn, PI_ERR_INT_MASK_A); REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_A, (misc & ~PI_ERR_UNCAC_UNCORR_A)); misc = REMOTE_HUB_PI_L(nasid, sn, PI_ERR_INT_MASK_B); REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_B, (misc & ~PI_ERR_UNCAC_UNCORR_B)); } /* * enable all error indicators to turn on, in case of errors. * * This is not good on single cpu node boards. **** LOCAL_HUB_S(PI_SYSAD_ERRCHK_EN, PI_SYSAD_CHECK_ALL); */ for(sn=0; sn<NUM_SUBNODES; sn++) { REMOTE_HUB_PI_S(nasid, sn, PI_ERR_STATUS1_A_CLR, 0); REMOTE_HUB_PI_S(nasid, sn, PI_ERR_STATUS1_B_CLR, 0); } /* Set up stack for each present processor */ for(sn=0; sn<NUM_SUBNODES; sn++) { if (REMOTE_HUB_PI_L(nasid, sn, PI_CPU_PRESENT_A)) { SN0_ERROR_LOG(cnode)->el_spool_cur_addr[0] = SN0_ERROR_LOG(cnode)->el_spool_last_addr[0] = REMOTE_HUB_PI_L(nasid, sn, PI_ERR_STACK_ADDR_A); } if (REMOTE_HUB_PI_L(nasid, sn, PI_CPU_PRESENT_B)) { SN0_ERROR_LOG(cnode)->el_spool_cur_addr[1] = SN0_ERROR_LOG(cnode)->el_spool_last_addr[1] = REMOTE_HUB_PI_L(nasid, sn, PI_ERR_STACK_ADDR_B); } } PI_SPOOL_SIZE_BYTES = ERR_STACK_SIZE_BYTES(REMOTE_HUB_L(nasid, PI_ERR_STACK_SIZE)); #ifdef BRINGUP /* BRINGUP: The following code looks like a check to make sure the prom set up the error spool correctly for 2 processors. I don't think it is needed. */ for(sn=0; sn<NUM_SUBNODES; sn++) { if (REMOTE_HUB_PI_L(nasid, sn, PI_CPU_PRESENT_B)) { __psunsigned_t addr_a = REMOTE_HUB_PI_L(nasid, sn, PI_ERR_STACK_ADDR_A); __psunsigned_t addr_b = REMOTE_HUB_PI_L(nasid, sn, PI_ERR_STACK_ADDR_B); if ((addr_a & ~0xff) == (addr_b & ~0xff)) { REMOTE_HUB_PI_S(nasid, sn, PI_ERR_STACK_ADDR_B, addr_b + PI_SPOOL_SIZE_BYTES); SN0_ERROR_LOG(cnode)->el_spool_cur_addr[1] = SN0_ERROR_LOG(cnode)->el_spool_last_addr[1] = REMOTE_HUB_PI_L(nasid, sn, PI_ERR_STACK_ADDR_B); } } } #endif /* BRINGUP */ /* programming our own hub. Enable error_int_pend intr. * If both present, CPU A takes CPU b's error interrupts and any * generic ones. CPU B takes CPU A error ints. */ if (cause_intr_connect (SRB_ERR_IDX, (intr_func_t)(hubpi_eint_handler), SR_ALL_MASK|SR_IE)) { cmn_err(ERR_WARN, "hub_error_init: cause_intr_connect failed on %d", cnode); } } else { /* programming remote hub. The only valid reason that this * is called will be on headless hubs. No interrupts */ for(sn=0; sn<NUM_SUBNODES; sn++) { REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_A, 0); /* not necessary */ REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_B, 0); /* not necessary */ } } #endif /* ajm */ /* * Now setup the hub ii and ni error interrupt handler. */ hubii_eint_init(cnode); hubni_eint_init(cnode); #ifdef ajm /*** XXX FIXME XXX resolve the following***/ /* INT_PEND1 bits set up for one hub only: * SHUTDOWN_INTR * MD_COR_ERR_INTR * COR_ERR_INTR_A and COR_ERR_INTR_B should be sent to the * appropriate CPU only. */ if (cnode == 0) { error_consistency_check.eps_state = 0; error_consistency_check.eps_cpuid = -1; spinlock_init(&error_consistency_check.eps_lock, "error_dump_lock"); } #endif nodepda->huberror_ticks = HUB_ERROR_PERIOD; return; }