Esempio n. 1
0
void
pciio_device_info_unregister(devfs_handle_t connectpt,
                             pciio_info_t pciio_info)
{
    char		name[32];
    devfs_handle_t	pconn;

    if (!pciio_info)
        return;

    pciio_slot_func_to_name(name,
                            pciio_info->c_slot,
                            pciio_info->c_func);

    hwgraph_edge_remove(connectpt,name,&pconn);
    pciio_info_set(pconn,0);

    /* Remove the link to our pci provider */
    hwgraph_edge_remove(pconn, EDGE_LBL_MASTER, NULL);


    hwgraph_vertex_unref(pconn);
    hwgraph_vertex_destroy(pconn);

}
Esempio n. 2
0
static void
baseio_ctlr_num_set(void)
{
	char 			name[MAXDEVNAME];
	devfs_handle_t		console_vhdl, pci_vhdl, enet_vhdl;
	devfs_handle_t		ioc3_console_vhdl_get(void);


	DBG("baseio_ctlr_num_set; FIXME\n");
	console_vhdl = ioc3_console_vhdl_get();
	if (console_vhdl == GRAPH_VERTEX_NONE)
		return;
	/* Useful for setting up the system critical graph */
	baseio_console_vhdl = console_vhdl;

	vertex_to_name(console_vhdl,name,MAXDEVNAME);

	strcat(name,__DEVSTR1);
	pci_vhdl =  hwgraph_path_to_vertex(name);
	scsi_ctlr_nums_add(pci_vhdl);
	/* Unref the pci_vhdl due to the reference by hwgraph_path_to_vertex
	 */
	hwgraph_vertex_unref(pci_vhdl);

	vertex_to_name(console_vhdl, name, MAXDEVNAME);
	strcat(name, __DEVSTR4);
	enet_vhdl = hwgraph_path_to_vertex(name);

	/* Useful for setting up the system critical graph */
	baseio_enet_vhdl = enet_vhdl;

	device_controller_num_set(enet_vhdl, 0);
	/* Unref the enet_vhdl due to the reference by hwgraph_path_to_vertex
	 */
	hwgraph_vertex_unref(enet_vhdl);
}
Esempio n. 3
0
/*
 * 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;
}
Esempio n. 4
0
/*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! */
}
Esempio n. 5
0
/*
 * Put the logical controller number information in the 
 * scsi controller vertices for each scsi controller that
 * is in a "fixed position".
 */
static void
scsi_ctlr_nums_add(devfs_handle_t pci_vhdl)
{
	{
		int i;

		num_base_io_scsi_ctlr = NUM_BASE_IO_SCSI_CTLR;

		/* Initialize base_io_scsi_ctlr_vhdl array */
		for (i=0; i<NUM_BASE_IO_SCSI_CTLR; i++)
			base_io_scsi_ctlr_vhdl[i] = GRAPH_VERTEX_NONE;
	}
	{
	/*
	 * May want to consider changing the SN0 code, above, to work more like
	 * the way this works.
	 */
	devfs_handle_t base_ibrick_xbridge_vhdl;
	devfs_handle_t base_ibrick_xtalk_widget_vhdl;
	devfs_handle_t scsi_ctlr_vhdl;
	int i;
	graph_error_t rv;

	/*
	 * This is a table of "well-known" SCSI controllers and their well-known
	 * controller numbers.  The names in the table start from the base IBrick's
	 * Xbridge vertex, so the first component is the xtalk widget number.
	 */
	static struct {
		char	*base_ibrick_scsi_path;
		int	controller_number;
	} hardwired_scsi_controllers[] = {
		{"15/" EDGE_LBL_PCI "/1/" EDGE_LBL_SCSI_CTLR "/0", 0},
		{"15/" EDGE_LBL_PCI "/2/" EDGE_LBL_SCSI_CTLR "/0", 1},
		{"15/" EDGE_LBL_PCI "/3/" EDGE_LBL_SCSI_CTLR "/0", 2},
		{"14/" EDGE_LBL_PCI "/1/" EDGE_LBL_SCSI_CTLR "/0", 3},
		{"14/" EDGE_LBL_PCI "/2/" EDGE_LBL_SCSI_CTLR "/0", 4},
		{"15/" EDGE_LBL_PCI "/6/ohci/0/" EDGE_LBL_SCSI_CTLR "/0", 5},
		{NULL, -1} /* must be last */
	};

	base_ibrick_xtalk_widget_vhdl = hwgraph_connectpt_get(pci_vhdl);
	ASSERT_ALWAYS(base_ibrick_xtalk_widget_vhdl != GRAPH_VERTEX_NONE);

	base_ibrick_xbridge_vhdl = hwgraph_connectpt_get(base_ibrick_xtalk_widget_vhdl);
	ASSERT_ALWAYS(base_ibrick_xbridge_vhdl != GRAPH_VERTEX_NONE);
	hwgraph_vertex_unref(base_ibrick_xtalk_widget_vhdl);

	/*
	 * Iterate through the list of well-known SCSI controllers.
	 * For each controller found, set it's controller number according
	 * to the table.
	 */
	for (i=0; hardwired_scsi_controllers[i].base_ibrick_scsi_path != NULL; i++) {
		rv = hwgraph_path_lookup(base_ibrick_xbridge_vhdl,
			hardwired_scsi_controllers[i].base_ibrick_scsi_path, &scsi_ctlr_vhdl, NULL);

		if (rv != GRAPH_SUCCESS) /* No SCSI at this path */
			continue;

		ASSERT(hardwired_scsi_controllers[i].controller_number < NUM_BASE_IO_SCSI_CTLR);
		base_io_scsi_ctlr_vhdl[hardwired_scsi_controllers[i].controller_number] = scsi_ctlr_vhdl;
		device_controller_num_set(scsi_ctlr_vhdl, hardwired_scsi_controllers[i].controller_number);
		hwgraph_vertex_unref(scsi_ctlr_vhdl); /* (even though we're actually keeping a reference) */
	}

	hwgraph_vertex_unref(base_ibrick_xbridge_vhdl);
	}
}
Esempio n. 6
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);

}