コード例 #1
0
ファイル: mem_refcnt.c プロジェクト: dot-Sean/linux_kernels
/*ARGSUSED*/
int
mem_refcnt_open(devfs_handle_t *devp, mode_t oflag, int otyp, cred_t *crp)
{
        cnodeid_t node;
#ifndef CONFIG_IA64_SGI_SN1
	extern int numnodes;
#endif
        
        ASSERT( (hubspc_subdevice_t)(ulong)device_info_get(*devp) == HUBSPC_REFCOUNTERS );

        if (!cap_able(CAP_MEMORY_MGT)) {
                return (EPERM);
        }

        node = master_node_get(*devp);

        ASSERT( (node >= 0) && (node < numnodes) );

        if (NODEPDA(node)->migr_refcnt_counterbuffer == NULL) {
                return (ENODEV);
        }

        ASSERT( NODEPDA(node)->migr_refcnt_counterbase != NULL );
        ASSERT( NODEPDA(node)->migr_refcnt_cbsize != (size_t)0 );

        return (0);
}
コード例 #2
0
ファイル: mem_refcnt.c プロジェクト: dot-Sean/linux_kernels
/*ARGSUSED*/
int
mem_refcnt_mmap(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot)
{
        cnodeid_t node;
        int errcode;
        char* buffer;
        size_t blen;
#ifndef CONFIG_IA64_SGI_SN1
	extern int numnodes;
#endif
        
        ASSERT( (hubspc_subdevice_t)(ulong)device_info_get(dev) == HUBSPC_REFCOUNTERS );

        node = master_node_get(dev);

        ASSERT( (node >= 0) && (node < numnodes) );

        ASSERT( NODEPDA(node)->migr_refcnt_counterbuffer != NULL);
        ASSERT( NODEPDA(node)->migr_refcnt_counterbase != NULL );
        ASSERT( NODEPDA(node)->migr_refcnt_cbsize != 0 );

        /*
         * XXXX deal with prot's somewhere around here....
         */

        buffer = NODEPDA(node)->migr_refcnt_counterbuffer;
        blen = NODEPDA(node)->migr_refcnt_cbsize;

        /*
         * Force offset to be a multiple of sizeof(refcnt_t)
         * We round up.
         */

        off = (((off - 1)/sizeof(refcnt_t)) + 1) * sizeof(refcnt_t);

        if ( ((buffer + blen) - (buffer + off + len)) < 0 ) {
                return (EPERM);
        }

        errcode = v_mapphys(vt,
                            buffer + off,
                            len);

        return errcode;
}
コード例 #3
0
ファイル: ml_SN_intr.c プロジェクト: romanalexander/Trickles
cpuid_t
intr_heuristic(vertex_hdl_t dev,
               device_desc_t dev_desc,
               int	req_bit,
               int resflags,
               vertex_hdl_t owner_dev,
               char *name,
               int *resp_bit)
{
    cpuid_t		cpuid;
    cpuid_t		candidate = CPU_NONE;
    cnodeid_t	candidate_node;
    vertex_hdl_t	pconn_vhdl;
    pcibr_soft_t	pcibr_soft;
    int 		bit;
    static cnodeid_t last_node = 0;

    /* SN2 + pcibr addressing limitation */
    /* Due to this limitation, all interrupts from a given bridge must go to the name node.*/
    /* The interrupt must also be targetted for the same processor. */
    /* This limitation does not exist on PIC. */
    /* But, the processor limitation will stay.  The limitation will be similar to */
    /* the bedrock/xbridge limit regarding PI's */

    if ( (hwgraph_edge_get(dev, EDGE_LBL_PCI, &pconn_vhdl) == GRAPH_SUCCESS) &&
            ( (pcibr_soft = pcibr_soft_get(pconn_vhdl) ) != NULL) ) {
        if (pcibr_soft->bsi_err_intr) {
            candidate =  ((hub_intr_t)pcibr_soft->bsi_err_intr)->i_cpuid;
        }
    }


    if (candidate != CPU_NONE) {
        // The cpu was chosen already when we assigned the error interrupt.
        bit = intr_reserve_level(candidate,
                                 req_bit,
                                 resflags,
                                 owner_dev,
                                 name);
        if (bit < 0) {
            cpuid = CPU_NONE;
        } else {
            cpuid = candidate;
            *resp_bit = bit;
        }
    } else {
        // Need to choose one.  Try the controlling c-brick first.
        cpuid = intr_bit_reserve_test(CPU_NONE,
                                      0,
                                      master_node_get(dev),
                                      req_bit,
                                      0,
                                      owner_dev,
                                      name,
                                      resp_bit);
    }

    if (cpuid != CPU_NONE) {
        return cpuid;
    }

    if (candidate  != CPU_NONE) {
        printk("Cannot target interrupt to target node (%ld).\n",candidate);
        return CPU_NONE;
    } else {
        printk("Cannot target interrupt to closest node (0x%x) 0x%p\n",
               master_node_get(dev), (void *)owner_dev);
    }

    // We couldn't put it on the closest node.  Try to find another one.
    // Do a stupid round-robin assignment of the node.

    {
        int i;

        if (last_node >= numnodes) last_node = 0;
        for (i = 0, candidate_node = last_node; i < numnodes; candidate_node++,i++) {
            if (candidate_node == numnodes) candidate_node = 0;
            cpuid = intr_bit_reserve_test(CPU_NONE,
                                          0,
                                          candidate_node,
                                          req_bit,
                                          0,
                                          owner_dev,
                                          name,
                                          resp_bit);
            if (cpuid != CPU_NONE) {
                last_node = candidate_node + 1;
                return cpuid;
            }
        }
    }

    printk("cannot target interrupt: 0x%p\n",(void *)owner_dev);
    return CPU_NONE;
}
コード例 #4
0
ファイル: ml_iograph.c プロジェクト: ya-mouse/cnu-680pro
/* Define the system critical vertices and connect them through
 * a canonical parent-child relationships for easy traversal
 * during io error handling.
 */
static void
sys_critical_graph_init(void)
{
	devfs_handle_t		bridge_vhdl,master_node_vhdl;
	devfs_handle_t  		xbow_vhdl = GRAPH_VERTEX_NONE;
	extern devfs_handle_t	hwgraph_root;
	devfs_handle_t		pci_slot_conn;
	int			slot;
	devfs_handle_t		baseio_console_conn;

	DBG("sys_critical_graph_init: FIXME.\n");
	baseio_console_conn = hwgraph_connectpt_get(baseio_console_vhdl);

	if (baseio_console_conn == NULL) {
		return;
	}

	/* Get the vertex handle for the baseio bridge */
	bridge_vhdl = device_master_get(baseio_console_conn);

	/* Get the master node of the baseio card */
	master_node_vhdl = cnodeid_to_vertex(
				master_node_get(baseio_console_vhdl));
	
	/* Add the "root->node" part of the system critical graph */

	sys_critical_graph_vertex_add(hwgraph_root,master_node_vhdl);

	/* Check if we have a crossbow */
	if (hwgraph_traverse(master_node_vhdl,
			     EDGE_LBL_XTALK"/0",
			     &xbow_vhdl) == GRAPH_SUCCESS) {
		/* We have a crossbow.Add "node->xbow" part of the system 
		 * critical graph.
		 */
		sys_critical_graph_vertex_add(master_node_vhdl,xbow_vhdl);
		
		/* Add "xbow->baseio bridge" of the system critical graph */
		sys_critical_graph_vertex_add(xbow_vhdl,bridge_vhdl);

		hwgraph_vertex_unref(xbow_vhdl);
	} else 
		/* We donot have a crossbow. Add "node->baseio_bridge"
		 * part of the system critical graph.
		 */
		sys_critical_graph_vertex_add(master_node_vhdl,bridge_vhdl);

	/* Add all the populated PCI slot vertices to the system critical
	 * graph with the bridge vertex as the parent.
	 */
	for (slot = 0 ; slot < 8; slot++) {
		char	slot_edge[10];

		sprintf(slot_edge,"%d",slot);
		if (hwgraph_traverse(bridge_vhdl,slot_edge, &pci_slot_conn)
		    != GRAPH_SUCCESS)
			continue;
		sys_critical_graph_vertex_add(bridge_vhdl,pci_slot_conn);
		hwgraph_vertex_unref(pci_slot_conn);
	}

	hwgraph_vertex_unref(bridge_vhdl);

	/* Add the "ioc3 pci connection point  -> console ioc3" part 
	 * of the system critical graph
	 */

	if (hwgraph_traverse(baseio_console_vhdl,"..",&pci_slot_conn) ==
	    GRAPH_SUCCESS) {
		sys_critical_graph_vertex_add(pci_slot_conn, 
					      baseio_console_vhdl);
		hwgraph_vertex_unref(pci_slot_conn);
	}

	/* Add the "ethernet pci connection point  -> base ethernet" part of 
	 * the system  critical graph
	 */
	if (hwgraph_traverse(baseio_enet_vhdl,"..",&pci_slot_conn) ==
	    GRAPH_SUCCESS) {
		sys_critical_graph_vertex_add(pci_slot_conn, 
					      baseio_enet_vhdl);
		hwgraph_vertex_unref(pci_slot_conn);
	}

	/* Add the "scsi controller pci connection point  -> base scsi 
	 * controller" part of the system critical graph
	 */
	if (hwgraph_traverse(base_io_scsi_ctlr_vhdl[0],
			     "../..",&pci_slot_conn) == GRAPH_SUCCESS) {
		sys_critical_graph_vertex_add(pci_slot_conn, 
					      base_io_scsi_ctlr_vhdl[0]);
		hwgraph_vertex_unref(pci_slot_conn);
	}
	if (hwgraph_traverse(base_io_scsi_ctlr_vhdl[1],
			     "../..",&pci_slot_conn) == GRAPH_SUCCESS) {
		sys_critical_graph_vertex_add(pci_slot_conn, 
					      base_io_scsi_ctlr_vhdl[1]);
		hwgraph_vertex_unref(pci_slot_conn);
	}
	hwgraph_vertex_unref(baseio_console_conn);

}
コード例 #5
0
ファイル: mem_refcnt.c プロジェクト: dot-Sean/linux_kernels
/* ARGSUSED */
int
mem_refcnt_ioctl(devfs_handle_t dev,
                 int cmd,
                 void *arg,
                 int mode,
                 cred_t *cred_p,
                 int *rvalp)
{
        cnodeid_t node;
        int errcode;
	extern int numnodes;
        
        ASSERT( (hubspc_subdevice_t)(ulong)device_info_get(dev) == HUBSPC_REFCOUNTERS );

        node = master_node_get(dev);

        ASSERT( (node >= 0) && (node < numnodes) );

        ASSERT( NODEPDA(node)->migr_refcnt_counterbuffer != NULL);
        ASSERT( NODEPDA(node)->migr_refcnt_counterbase != NULL );
        ASSERT( NODEPDA(node)->migr_refcnt_cbsize != 0 );

        errcode = 0;
        
        switch (cmd) {
        case RCB_INFO_GET:
        {
                rcb_info_t rcb;
                
                rcb.rcb_len = NODEPDA(node)->migr_refcnt_cbsize;
                
                rcb.rcb_sw_sets = NODEPDA(node)->migr_refcnt_numsets;
                rcb.rcb_sw_counters_per_set = numnodes;
                rcb.rcb_sw_counter_size = sizeof(refcnt_t);

                rcb.rcb_base_pages = NODEPDA(node)->migr_refcnt_numsets /
                                     NUM_OF_HW_PAGES_PER_SW_PAGE();  
                rcb.rcb_base_page_size = NBPP;
                rcb.rcb_base_paddr = ctob(slot_getbasepfn(node, 0));
                
                rcb.rcb_cnodeid = node;
                rcb.rcb_granularity = MD_PAGE_SIZE;
#ifdef notyet
                rcb.rcb_hw_counter_max = MIGR_COUNTER_MAX_GET(node);
                rcb.rcb_diff_threshold = MIGR_THRESHOLD_DIFF_GET(node);
#endif
                rcb.rcb_abs_threshold = MIGR_THRESHOLD_ABS_GET(node);
                rcb.rcb_num_slots = node_getnumslots(node);

                if (COPYOUT(&rcb, arg, sizeof(rcb_info_t))) {
                        errcode = EFAULT;
                }

                break;
        }
        case RCB_SLOT_GET:
        {
                rcb_slot_t slot[MAX_MEM_SLOTS];
                int s;
                int nslots;

                nslots = node_getnumslots(node);
                ASSERT(nslots <= MAX_MEM_SLOTS);
                for (s = 0; s < nslots; s++) {
                        slot[s].base = (uint64_t)ctob(slot_getbasepfn(node, s));
#ifdef notyet
                        slot[s].size  = (uint64_t)ctob(slot_getsize(node, s));
#else
                        slot[s].size  = (uint64_t)1;
#endif
                }
                if (COPYOUT(&slot[0], arg, nslots * sizeof(rcb_slot_t))) {
                        errcode = EFAULT;
                }
                
                *rvalp = nslots;
                break;
        }
                
        default:
                errcode = EINVAL;
                break;

        }
        
        return errcode;
}