예제 #1
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! */
}
예제 #2
0
/*ARGSUSED */
int
pciio_error_handler(
		       vertex_hdl_t pciio_vhdl,
		       int error_code,
		       ioerror_mode_t mode,
		       ioerror_t *ioerror)
{
    pciio_info_t            pciio_info;
    vertex_hdl_t            pconn_vhdl;
    pciio_slot_t            slot;

    int                     retval;

#if DEBUG && ERROR_DEBUG
    printk("%v: pciio_error_handler\n", pciio_vhdl);
#endif

    IOERR_PRINTF(printk(KERN_NOTICE "%v: PCI Bus Error: Error code: %d Error mode: %d\n",
			 pciio_vhdl, error_code, mode));

    /* 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);

	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)) {
	short widgetdev;
	/*
	 * NOTE : 
	 * widgetdev is a 4byte value encoded as slot in the higher order
	 * 2 bytes and function in the lower order 2 bytes.
	 */
	IOERROR_GETVALUE(widgetdev, ioerror, widgetdev);
	slot = pciio_widgetdev_slot_get(widgetdev);

	/* 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);

		retval = pciio_info->c_efunc
		    (pciio_info->c_einfo, error_code, mode, ioerror);
		if (retval != IOERROR_UNHANDLED)
		    return retval;
	    }
	}
    }

    return (mode == MODE_DEVPROBE)
	? IOERROR_HANDLED	/* probes are OK */
	: IOERROR_UNHANDLED;	/* otherwise, foo! */
}