/** * eeh_report_resume - Tell device to resume normal operations * @data: eeh device * @userdata: return value * * This routine must be called to notify the device driver that it * could resume so that the device driver can do some initialization * to make the recovered device work again. */ static void *eeh_report_resume(void *data, void *userdata) { struct eeh_dev *edev = (struct eeh_dev *)data; struct pci_dev *dev = eeh_dev_to_pci_dev(edev); struct pci_driver *driver; if (!dev || eeh_dev_removed(edev)) return NULL; dev->error_state = pci_channel_io_normal; driver = eeh_pcid_get(dev); if (!driver) return NULL; eeh_enable_irq(dev); if (!driver->err_handler || !driver->err_handler->resume || (edev->mode & EEH_DEV_NO_HANDLER)) { edev->mode &= ~EEH_DEV_NO_HANDLER; eeh_pcid_put(dev); return NULL; } driver->err_handler->resume(dev); eeh_pcid_put(dev); return NULL; }
/** * eeh_report_reset - Tell device that slot has been reset * @data: eeh device * @userdata: return value * * This routine must be called while EEH tries to reset particular * PCI device so that the associated PCI device driver could take * some actions, usually to save data the driver needs so that the * driver can work again while the device is recovered. */ static void *eeh_report_reset(void *data, void *userdata) { struct eeh_dev *edev = (struct eeh_dev *)data; struct pci_dev *dev = eeh_dev_to_pci_dev(edev); enum pci_ers_result rc, *res = userdata; struct pci_driver *driver; if (!dev || eeh_dev_removed(edev)) return NULL; dev->error_state = pci_channel_io_normal; driver = eeh_pcid_get(dev); if (!driver) return NULL; eeh_enable_irq(dev); if (!driver->err_handler || !driver->err_handler->slot_reset || (edev->mode & EEH_DEV_NO_HANDLER)) { eeh_pcid_put(dev); return NULL; } rc = driver->err_handler->slot_reset(dev); if ((*res == PCI_ERS_RESULT_NONE) || (*res == PCI_ERS_RESULT_RECOVERED)) *res = rc; if (*res == PCI_ERS_RESULT_DISCONNECT && rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; eeh_pcid_put(dev); return NULL; }
/** * eeh_report_resume - Tell device to resume normal operations * @dev: PCI device * @userdata: return value * * This routine must be called to notify the device driver that it * could resume so that the device driver can do some initialization * to make the recovered device work again. */ static int eeh_report_resume(struct pci_dev *dev, void *userdata) { struct pci_driver *driver; device_lock(&dev->dev); dev->error_state = pci_channel_io_normal; driver = eeh_pcid_get(dev); if (!driver) goto out; eeh_enable_irq(dev); if (!driver->err_handler || !driver->err_handler->resume) { eeh_pcid_put(dev); goto out; } driver->err_handler->resume(dev); eeh_pcid_put(dev); out: device_unlock(&dev->dev); return 0; }
/** * eeh_report_reset - Tell device that slot has been reset * @dev: PCI device * @userdata: return value * * This routine must be called while EEH tries to reset particular * PCI device so that the associated PCI device driver could take * some actions, usually to save data the driver needs so that the * driver can work again while the device is recovered. */ static int eeh_report_reset(struct pci_dev *dev, void *userdata) { enum pci_ers_result rc, *res = userdata; struct pci_driver *driver; device_lock(&dev->dev); dev->error_state = pci_channel_io_normal; driver = eeh_pcid_get(dev); if (!driver) goto out; eeh_enable_irq(dev); if (!driver->err_handler || !driver->err_handler->slot_reset) { eeh_pcid_put(dev); goto out; } rc = driver->err_handler->slot_reset(dev); if ((*res == PCI_ERS_RESULT_NONE) || (*res == PCI_ERS_RESULT_RECOVERED)) *res = rc; if (*res == PCI_ERS_RESULT_DISCONNECT && rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; eeh_pcid_put(dev); out: device_unlock(&dev->dev); return 0; }
static int eeh_report_resume(struct pci_dev *dev, void *userdata) { struct pci_driver *driver = dev->driver; dev->error_state = pci_channel_io_normal; if (!driver) return 0; eeh_enable_irq(dev); if (!driver->err_handler || !driver->err_handler->resume) return 0; driver->err_handler->resume(dev); return 0; }
static int eeh_report_reset(struct pci_dev *dev, void *userdata) { enum pci_ers_result rc, *res = userdata; struct pci_driver *driver = dev->driver; if (!driver) return 0; dev->error_state = pci_channel_io_normal; eeh_enable_irq(dev); if (!driver->err_handler || !driver->err_handler->slot_reset) return 0; rc = driver->err_handler->slot_reset(dev); if ((*res == PCI_ERS_RESULT_NONE) || (*res == PCI_ERS_RESULT_RECOVERED)) *res = rc; if (*res == PCI_ERS_RESULT_DISCONNECT && rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; return 0; }