/*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! */ }
/*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! */ }