示例#1
0
/*
 * devfn_to_vertex() - returns the vertex of the device given the bus, slot, 
 *	and function numbers.
 */
devfs_handle_t
devfn_to_vertex(unsigned char busnum, unsigned int devfn)
{

	int slot = 0;
	int func = 0;
	char	name[16];
	devfs_handle_t  pci_bus = NULL;
	devfs_handle_t	device_vertex = (devfs_handle_t)NULL;

	/*
	 * Go get the pci bus vertex.
	 */
	pci_bus = pci_bus_to_vertex(busnum);
	if (!pci_bus) {
		/*
		 * During probing, the Linux pci code invents non-existent
		 * bus numbers and pci_dev structures and tries to access
		 * them to determine existence. Don't crib during probing.
		 */
		if (done_probing)
			printk("devfn_to_vertex: Invalid bus number %d given.\n", busnum);
		return(NULL);
	}


	/*
	 * Go get the slot&function vertex.
	 * Should call pciio_slot_func_to_name() when ready.
	 */
	slot = PCI_SLOT(devfn);
	func = PCI_FUNC(devfn);

	/*
	 * For a NON Multi-function card the name of the device looks like:
	 * ../pci/1, ../pci/2 ..
	 */
	if (func == 0) {
        	sprintf(name, "%d", slot);
		if (hwgraph_traverse(pci_bus, name, &device_vertex) == 
			GRAPH_SUCCESS) {
			if (device_vertex) {
				return(device_vertex);
			}
		}
	}
			
	/*
	 * This maybe a multifunction card.  It's names look like:
	 * ../pci/1a, ../pci/1b, etc.
	 */
	sprintf(name, "%d%c", slot, 'a'+func);
	if (hwgraph_traverse(pci_bus, name, &device_vertex) != GRAPH_SUCCESS) {
		if (!device_vertex) {
			return(NULL);
		}
	}

	return(device_vertex);
}
示例#2
0
/*
 * For each PCI bridge connected to the xswitch, add a link from the
 * board's klconfig info to the bridge's hwgraph vertex.  This lets
 * the FRU analyzer find the bridge without traversing the hardware
 * graph and risking hangs.
 */
static void
io_link_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnodeid)
{
	xwidgetnum_t		widgetnum;
	char 			pathname[128];
	devfs_handle_t		vhdl;
	nasid_t			nasid, peer_nasid;
	lboard_t		*board;



	/* And its connected hub's nasids */
	nasid = COMPACT_TO_NASID_NODEID(cnodeid);
	peer_nasid = NODEPDA(cnodeid)->xbow_peer;

	/* 
	 * Look for paths matching "<widgetnum>/pci" under xswitchv.
	 * For every widget, init. its lboard's hwgraph link.  If the
	 * board has a PCI bridge, point the link to it.
	 */
	for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX;
		 widgetnum++) {
		sprintf(pathname, "%d", widgetnum);
		if (hwgraph_traverse(xswitchv, pathname, &vhdl) !=
		    GRAPH_SUCCESS)
			continue;

		board = find_lboard_module((lboard_t *)KL_CONFIG_INFO(nasid),
				NODEPDA(cnodeid)->module_id);
		if (board == NULL && peer_nasid != INVALID_NASID) {
			/*
			 * Try to find the board on our peer
			 */
			board = find_lboard_module(
				(lboard_t *)KL_CONFIG_INFO(peer_nasid),
				NODEPDA(cnodeid)->module_id);
		}
		if (board == NULL) {
#if defined(SUPPORT_PRINTING_V_FORMAT)
			printk(KERN_WARNING  "Could not find PROM info for vertex %v, "
				"FRU analyzer may fail",
				vhdl);
#else
			printk(KERN_WARNING  "Could not find PROM info for vertex 0x%p, "
				"FRU analyzer may fail",
				(void *)vhdl);
#endif
			return;
		}

		sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum);
		if (hwgraph_traverse(xswitchv, pathname, &vhdl) == 
		    GRAPH_SUCCESS)
			board->brd_graph_link = vhdl;
		else
			board->brd_graph_link = GRAPH_VERTEX_NONE;
	}
}
示例#3
0
/*
 * hub_device_inquiry
 *	Find out the xtalk widget related information stored in this
 *	hub's II.
 */
void
hub_device_inquiry(devfs_handle_t	xbus_vhdl, xwidgetnum_t widget)
{
    devfs_handle_t	xconn, hub_vhdl;
    char		widget_name[8];
    hubreg_t	ii_iidem,ii_iiwa, ii_iowa;
    hubinfo_t	hubinfo;
    nasid_t		nasid;
    int		d;

    sprintf(widget_name, "%d", widget);
    if (hwgraph_traverse(xbus_vhdl, widget_name, &xconn)
            != GRAPH_SUCCESS)
        return;

    hub_vhdl = device_master_get(xconn);
    if (hub_vhdl == GRAPH_VERTEX_NONE)
        return;

    hubinfo_get(hub_vhdl, &hubinfo);
    if (!hubinfo)
        return;

    nasid = hubinfo->h_nasid;

    ii_iidem	= REMOTE_HUB_L(nasid, IIO_IIDEM);
    ii_iiwa 	= REMOTE_HUB_L(nasid, IIO_IIWA);
    ii_iowa 	= REMOTE_HUB_L(nasid, IIO_IOWA);

#if defined(SUPPORT_PRINTING_V_FORMAT)
    cmn_err(CE_CONT, "Inquiry Info for %v\n", xconn);
#else
    cmn_err(CE_CONT, "Inquiry Info for 0x%p\n", &xconn);
#endif

    cmn_err(CE_CONT,"\tDevices shutdown [ ");

    for (d = 0 ; d <= 7 ; d++)
        if (!(ii_iidem & (IIO_IIDEM_WIDGETDEV_MASK(widget,d))))
            cmn_err(CE_CONT, " %d", d);

    cmn_err(CE_CONT,"]\n");

    cmn_err(CE_CONT,
            "\tInbound access ? %s\n",
            ii_iiwa & IIO_IIWA_WIDGET(widget) ? "yes" : "no");

    cmn_err(CE_CONT,
            "\tOutbound access ? %s\n",
            ii_iowa & IIO_IOWA_WIDGET(widget) ? "yes" : "no");

}
示例#4
0
文件: pciio.c 项目: hugh712/Jollen
/*
 * pciio_cardinfo_get
 *
 * Get the pciio info structure corresponding to the
 * specified PCI "slot" (we like it when the same index
 * number is used for the PCI IDSEL, the REQ/GNT pair,
 * and the interrupt line being used for INTA. We like
 * it so much we call it the slot number).
 */
static pciio_info_t
pciio_cardinfo_get(
    devfs_handle_t pciio_vhdl,
    pciio_slot_t pci_slot)
{
    char                    namebuf[16];
    pciio_info_t	    info = 0;
    devfs_handle_t	    conn;

    pciio_slot_func_to_name(namebuf, pci_slot, PCIIO_FUNC_NONE);
    if (GRAPH_SUCCESS ==
            hwgraph_traverse(pciio_vhdl, namebuf, &conn)) {
        info = pciio_info_chk(conn);
        hwgraph_vertex_unref(conn);
    }

    return info;
}
示例#5
0
文件: pciio.c 项目: hugh712/Jollen
/*ARGSUSED */
int
pciio_error_handler(
    devfs_handle_t pciio_vhdl,
    int error_code,
    ioerror_mode_t mode,
    ioerror_t *ioerror)
{
    pciio_info_t            pciio_info;
    devfs_handle_t            pconn_vhdl;
#if USRPCI
    devfs_handle_t            usrpci_v;
#endif
    pciio_slot_t            slot;

    int                     retval;
#if defined(CONFIG_SGI_IO_ERROR_HANDLING)
    error_state_t	    e_state;
#endif

#if DEBUG && ERROR_DEBUG
#if defined(SUPPORT_PRINTING_V_FORMAT)
    printk("%v: pciio_error_handler\n", pciio_vhdl);
#else
    printk("0x%x: pciio_error_handler\n", pciio_vhdl);
#endif
#endif

#if defined(SUPPORT_PRINTING_V_FORMAT)
    IOERR_PRINTF(printk("%v: PCI Bus Error: Error code: %d Error mode: %d\n",
                        pciio_vhdl, error_code, mode));
#else
    IOERR_PRINTF(printk("0x%x: PCI Bus Error: Error code: %d Error mode: %d\n",
                        pciio_vhdl, error_code, mode));
#endif

    /* If there is an error handler sitting on
     * the "no-slot" connection point, give it
     * first crack at the error. NOTE: it is
     * quite possible that this function may
     * do further refining of the ioerror.
     */
    pciio_info = pciio_cardinfo_get(pciio_vhdl, PCIIO_SLOT_NONE);
    if (pciio_info && pciio_info->c_efunc) {
        pconn_vhdl = pciio_info_dev_get(pciio_info);
#if defined(CONFIG_SGI_IO_ERROR_HANDLING)
        e_state = error_state_get(pciio_vhdl);

        if (e_state == ERROR_STATE_ACTION)
            (void)error_state_set(pciio_vhdl, ERROR_STATE_NONE);

        if (error_state_set(pconn_vhdl,e_state) ==
                ERROR_RETURN_CODE_CANNOT_SET_STATE)
            return(IOERROR_UNHANDLED);
#endif
        retval = pciio_info->c_efunc
                 (pciio_info->c_einfo, error_code, mode, ioerror);
        if (retval != IOERROR_UNHANDLED)
            return retval;
    }

    /* Is the error associated with a particular slot?
     */
    if (IOERROR_FIELDVALID(ioerror, widgetdev)) {
        /*
         * NOTE :
         * widgetdev is a 4byte value encoded as slot in the higher order
         * 2 bytes and function in the lower order 2 bytes.
         */
#ifdef LATER
        slot = pciio_widgetdev_slot_get(IOERROR_GETVALUE(ioerror, widgetdev));
#else
        slot = 0;
#endif

        /* If this slot has an error handler,
         * deliver the error to it.
         */
        pciio_info = pciio_cardinfo_get(pciio_vhdl, slot);
        if (pciio_info != NULL) {
            if (pciio_info->c_efunc != NULL) {

                pconn_vhdl = pciio_info_dev_get(pciio_info);
#if defined(CONFIG_SGI_IO_ERROR_HANDLING)
                e_state = error_state_get(pciio_vhdl);


                if (e_state == ERROR_STATE_ACTION)
                    (void)error_state_set(pciio_vhdl, ERROR_STATE_NONE);



                if (error_state_set(pconn_vhdl,e_state) ==
                        ERROR_RETURN_CODE_CANNOT_SET_STATE)
                    return(IOERROR_UNHANDLED);
#endif
                retval = pciio_info->c_efunc
                         (pciio_info->c_einfo, error_code, mode, ioerror);
                if (retval != IOERROR_UNHANDLED)
                    return retval;
            }

#if USRPCI
            /* If the USRPCI driver is available and
             * knows about this connection point,
             * deliver the error to it.
             *
             * OK to use pconn_vhdl here, even though we
             * have already UNREF'd it, since we know that
             * it is not going away.
             */
            pconn_vhdl = pciio_info_dev_get(pciio_info);
            if (GRAPH_SUCCESS ==
                    hwgraph_traverse(pconn_vhdl, EDGE_LBL_USRPCI, &usrpci_v)) {
                retval = usrpci_error_handler
                         (usrpci_v, error_code, IOERROR_GETVALUE(ioerror, busaddr));
                hwgraph_vertex_unref(usrpci_v);
                if (retval != IOERROR_UNHANDLED) {
                    /*
                     * This unref is not needed.  If this code is called often enough,
                     * the system will crash, due to vertex reference count reaching 0,
                     * causing vertex to be unallocated.  -jeremy
                     * hwgraph_vertex_unref(pconn_vhdl);
                     */
                    return retval;
                }
            }
#endif
        }
    }

    return (mode == MODE_DEVPROBE)
           ? IOERROR_HANDLED	/* probes are OK */
           : IOERROR_UNHANDLED;	/* otherwise, foo! */
}
示例#6
0
static void __init
klhwg_connect_hubs(vertex_hdl_t hwgraph_root)
{
	nasid_t nasid;
	cnodeid_t cnode;
	lboard_t *brd;
	klhub_t *hub;
	lboard_t *dest_brd;
	vertex_hdl_t hub_hndl;
	vertex_hdl_t dest_hndl;
	char path_buffer[50];
	char dest_path[50];
	graph_error_t rc;
	int port;

	for (cnode = 0; cnode < numionodes; cnode++) {
		nasid = cnodeid_to_nasid(cnode);

		brd = find_lboard_any((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA);

		hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
		ASSERT(hub);

		for (port = 1; port <= MAX_NI_PORTS; port++) {
			if (hub->hub_port[port].port_nasid == INVALID_NASID) {
				continue; /* Port not active */
			}

			if (nasid_to_cnodeid(hub->hub_port[port].port_nasid) == INVALID_CNODEID)
				continue;

			/* Generate a hardware graph path for this board. */
			board_to_path(brd, path_buffer);
			rc = hwgraph_traverse(hwgraph_root, path_buffer, &hub_hndl);

			if (rc != GRAPH_SUCCESS)
				printk(KERN_WARNING  "Can't find hub: %s", path_buffer);

			dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
					hub->hub_port[port].port_nasid,
					hub->hub_port[port].port_offset);

			/* Generate a hardware graph path for this board. */
			board_to_path(dest_brd, dest_path);

			rc = hwgraph_traverse(hwgraph_root, dest_path, &dest_hndl);

			if (rc != GRAPH_SUCCESS) {
				if (KL_CONFIG_DUPLICATE_BOARD(dest_brd))
					continue;
				printk("Can't find board: %s", dest_path);
				return;
			} else {
				char buf[1024];

				rc = hwgraph_path_add(hub_hndl, EDGE_LBL_INTERCONNECT, &hub_hndl);

				HWGRAPH_DEBUG(__FILE__, __FUNCTION__, __LINE__, hub_hndl, NULL, "Created link path.\n");

				sprintf(buf,"%s/%s",path_buffer,EDGE_LBL_INTERCONNECT);
				rc = hwgraph_traverse(hwgraph_root, buf, &hub_hndl);
				sprintf(buf,"%d",port);
				rc = hwgraph_edge_add(hub_hndl, dest_hndl, buf);

				HWGRAPH_DEBUG(__FILE__, __FUNCTION__, __LINE__, hub_hndl, dest_hndl, "Created edge %s from vhdl1 to vhdl2.\n", buf);

				if (rc != GRAPH_SUCCESS) {
					printk("Can't create edge: %s/%s to vertex 0x%p, error 0x%x\n",
							path_buffer, dest_path, (void *)dest_hndl, rc);
					return;
				}
			}
		}
	}
}
示例#7
0
/* ARGSUSED */
static void __init
klhwg_connect_one_router(vertex_hdl_t hwgraph_root, lboard_t *brd,
			 cnodeid_t cnode, nasid_t nasid)
{
	klrou_t *router;
	char path_buffer[50];
	char dest_path[50];
	vertex_hdl_t router_hndl;
	vertex_hdl_t dest_hndl;
	int rc;
	int port;
	lboard_t *dest_brd;

	/* Don't add duplicate boards. */
	if (brd->brd_flags & DUPLICATE_BOARD) {
		return;
	}

	/* Generate a hardware graph path for this board. */
	board_to_path(brd, path_buffer);

	rc = hwgraph_traverse(hwgraph_root, path_buffer, &router_hndl);

	if (rc != GRAPH_SUCCESS)
			return;

	if (rc != GRAPH_SUCCESS)
		printk(KERN_WARNING  "Can't find router: %s", path_buffer);

	/* We don't know what to do with multiple router components */
	if (brd->brd_numcompts != 1) {
		printk("klhwg_connect_one_router: %d cmpts on router\n",
			brd->brd_numcompts);
		return;
	}


	/* Convert component 0 to klrou_t ptr */
	router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd),
					      brd->brd_compts[0]);

	for (port = 1; port <= MAX_ROUTER_PORTS; port++) {
		/* See if the port's active */
		if (router->rou_port[port].port_nasid == INVALID_NASID) {
			GRPRINTF(("klhwg_connect_one_router: port %d inactive.\n",
				 port));
			continue;
		}
		if (nasid_to_cnodeid(router->rou_port[port].port_nasid) 
		    == INVALID_CNODEID) {
			continue;
		}

		dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
				router->rou_port[port].port_nasid,
				router->rou_port[port].port_offset);

		/* Generate a hardware graph path for this board. */
		board_to_path(dest_brd, dest_path);

		rc = hwgraph_traverse(hwgraph_root, dest_path, &dest_hndl);

		if (rc != GRAPH_SUCCESS) {
			if (KL_CONFIG_DUPLICATE_BOARD(dest_brd))
				continue;
			printk("Can't find router: %s", dest_path);
			return;
		}

		sprintf(dest_path, "%d", port);

		rc = hwgraph_edge_add(router_hndl, dest_hndl, dest_path);

		if (rc == GRAPH_DUP) {
			GRPRINTF(("Skipping port %d. nasid %d %s/%s\n",
				  port, router->rou_port[port].port_nasid,
				  path_buffer, dest_path));
			continue;
		}

		if (rc != GRAPH_SUCCESS) {
			printk("Can't create edge: %s/%s to vertex 0x%p error 0x%x\n",
				path_buffer, dest_path, (void *)dest_hndl, rc);
			return;
		}
		HWGRAPH_DEBUG(__FILE__, __FUNCTION__, __LINE__, router_hndl, dest_hndl, "Created edge %s from vhdl1 to vhdl2.\n", dest_path);
		
	}
}
示例#8
0
/* 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);

}
示例#9
0
文件: pic.c 项目: 12019/hg556a_source
/*
 * If this PIC is attached to two Cbricks ("dual-ported") then
 * attach each bus to opposite Cbricks.
 *
 * If successful, return a new vertex suitable for attaching the PIC bus.
 * If not successful, return zero and both buses will attach to the
 * vertex passed into pic_attach().
 */
static vertex_hdl_t
pic_bus1_redist(nasid_t nasid, vertex_hdl_t conn_v)
{
	cnodeid_t cnode = nasid_to_cnodeid(nasid);
	cnodeid_t xbow_peer = -1;
	char pathname[256], peer_path[256], tmpbuf[256];
	char *p;
	int rc;
	vertex_hdl_t peer_conn_v, hubv;
	int pos;
	slabid_t slab;

	if (NODEPDA(cnode)->xbow_peer >= 0) {			/* if dual-ported */
		/* create a path for this widget on the peer Cbrick */
		/* pcibr widget hw/module/001c11/slab/0/Pbrick/xtalk/12 */
		/* sprintf(pathname, "%v", conn_v); */
		xbow_peer = nasid_to_cnodeid(NODEPDA(cnode)->xbow_peer);
		pos = hwgfs_generate_path(conn_v, tmpbuf, 256);
		strcpy(pathname, &tmpbuf[pos]);
		p = pathname + strlen("hw/module/001c01/slab/0/");

		memset(tmpbuf, 0, 16);
		format_module_id(tmpbuf, geo_module((NODEPDA(xbow_peer))->geoid), MODULE_FORMAT_BRIEF);
		slab = geo_slab((NODEPDA(xbow_peer))->geoid);
		sprintf(peer_path, "module/%s/slab/%d/%s", tmpbuf, (int)slab, p); 
		
		/* Look for vertex for this widget on the peer Cbrick.
		 * Expect GRAPH_NOT_FOUND.
		 */
		rc = hwgraph_traverse(hwgraph_root, peer_path, &peer_conn_v);
		if (GRAPH_SUCCESS == rc)
			printk("pic_attach: found unexpected vertex: 0x%lx\n",
								(uint64_t)peer_conn_v);
		else if (GRAPH_NOT_FOUND != rc) {
			printk("pic_attach: hwgraph_traverse unexpectedly"
					" returned 0x%x\n", rc);
		} else {
			/* try to add the widget vertex to the peer Cbrick */
			rc = hwgraph_path_add(hwgraph_root, peer_path, &peer_conn_v);

			if (GRAPH_SUCCESS != rc)
			    printk("pic_attach: hwgraph_path_add"
						" failed with 0x%x\n", rc);
			else {
			    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v,
					"pic_bus1_redist: added vertex %v\n", peer_conn_v)); 

			    /* Now hang appropiate stuff off of the new
			     * vertex.	We bail out if we cannot add something.
			     * In that case, we don't remove the newly added
			     * vertex but that should be safe and we don't
			     * really expect the additions to fail anyway.
			     */
			    if (!pic_bus1_widget_info_dup(conn_v, peer_conn_v, 
							  xbow_peer, peer_path))
					return 0;

			    hubv = cnodeid_to_vertex(xbow_peer);
			    ASSERT(hubv != GRAPH_VERTEX_NONE);
			    device_master_set(peer_conn_v, hubv);
			    xtalk_provider_register(hubv, &hub_provider);
			    xtalk_provider_startup(hubv);
			    return peer_conn_v;
			}
		}
	}
	return 0;
}
示例#10
0
/*
 * pci_bus_map_create() - Called by pci_bus_to_hcl_cvlink() to finish the job.
 *
 *	Linux PCI Bus numbers are assigned from lowest module_id numbers
 *	(rack/slot etc.) starting from HUB_WIDGET_ID_MAX down to 
 *	HUB_WIDGET_ID_MIN:
 *		widgetnum 15 gets lower Bus Number than widgetnum 14 etc.
 *
 *	Given 2 modules 001c01 and 001c02 we get the following mappings:
 *		001c01, widgetnum 15 = Bus number 0
 *		001c01, widgetnum 14 = Bus number 1
 *		001c02, widgetnum 15 = Bus number 3
 *		001c02, widgetnum 14 = Bus number 4
 *		etc.
 *
 * The rational for starting Bus Number 0 with Widget number 15 is because 
 * the system boot disks are always connected via Widget 15 Slot 0 of the 
 * I-brick.  Linux creates /dev/sd* devices(naming) strating from Bus Number 0 
 * Therefore, /dev/sda1 will be the first disk, on Widget 15 of the lowest 
 * module id(Master Cnode) of the system.
 *	
 */
static int 
pci_bus_map_create(devfs_handle_t xtalk)
{

	devfs_handle_t master_node_vertex = NULL;
	devfs_handle_t xwidget = NULL;
	devfs_handle_t pci_bus = NULL;
	hubinfo_t hubinfo = NULL;
	xwidgetnum_t widgetnum;
	char pathname[128];
	graph_error_t rv;

	/*
	 * Loop throught this vertex and get the Xwidgets ..
	 */
	for (widgetnum = HUB_WIDGET_ID_MAX; widgetnum >= HUB_WIDGET_ID_MIN; widgetnum--) {
#if 0
        {
                int pos;
                char dname[256];
                pos = devfs_generate_path(xtalk, dname, 256);
                printk("%s : path= %s\n", __FUNCTION__, &dname[pos]);
        }
#endif

		sprintf(pathname, "%d", widgetnum);
		xwidget = NULL;
		
		/*
		 * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget
		 *	     /hw/module/001c16/Pbrick/xtalk/8/pci/1 is device
		 */
		rv = hwgraph_traverse(xtalk, pathname, &xwidget);
		if ( (rv != GRAPH_SUCCESS) ) {
			if (!xwidget)
				continue;
		}

		sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum);
		pci_bus = NULL;
		if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS)
			if (!pci_bus)
				continue;

		/*
		 * Assign the correct bus number and also the nasid of this 
		 * pci Xwidget.
		 * 
		 * Should not be any race here ...
		 */
		num_bridges++;
		busnum_to_pcibr_vhdl[num_bridges - 1] = pci_bus;

		/*
		 * Get the master node and from there get the NASID.
		 */
		master_node_vertex = device_master_get(xwidget);
		if (!master_node_vertex) {
			printk("WARNING: pci_bus_map_create: Unable to get .master for vertex 0x%p\n", (void *)xwidget);
		}
	
		hubinfo_get(master_node_vertex, &hubinfo);
		if (!hubinfo) {
			printk("WARNING: pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p\n", (void *)master_node_vertex);
			return(1);
		} else {
			busnum_to_nid[num_bridges - 1] = hubinfo->h_nasid;
		}

		/*
		 * Pre assign DMA maps needed for 32 Bits Page Map DMA.
		 */
		busnum_to_atedmamaps[num_bridges - 1] = (void *) kmalloc(
			sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL);
		if (!busnum_to_atedmamaps[num_bridges - 1])
			printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget);

		memset(busnum_to_atedmamaps[num_bridges - 1], 0x0, 
			sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS);

	}

        return(0);
}