static struct workqueue_struct *device_reset_wq;
static struct workqueue_struct *device_sriov_wq;
-static pci_ers_result_t adf_error_detected(struct pci_dev *pdev,
- pci_channel_state_t state)
+static pci_ers_result_t reset_prepare(struct pci_dev *pdev)
{
struct adf_accel_dev *accel_dev = adf_devmgr_pci_to_accel_dev(pdev);
- dev_info(&pdev->dev, "Acceleration driver hardware error detected.\n");
if (!accel_dev) {
dev_err(&pdev->dev, "Can't find acceleration device\n");
return PCI_ERS_RESULT_DISCONNECT;
}
- if (state == pci_channel_io_perm_failure) {
- dev_err(&pdev->dev, "Can't recover from device error\n");
- return PCI_ERS_RESULT_DISCONNECT;
- }
-
if (!adf_dev_started(accel_dev))
return PCI_ERS_RESULT_CAN_RECOVER;
- adf_error_notifier(accel_dev);
- adf_pf2vf_notify_fatal_error(accel_dev);
set_bit(ADF_STATUS_RESTARTING, &accel_dev->status);
if (accel_dev->hw_device->exit_arb) {
dev_dbg(&pdev->dev, "Disabling arbitration\n");
return PCI_ERS_RESULT_NEED_RESET;
}
+static pci_ers_result_t reset_done(struct pci_dev *pdev)
+{
+ struct adf_accel_dev *accel_dev = adf_devmgr_pci_to_accel_dev(pdev);
+ int res;
+
+ if (!accel_dev) {
+ dev_err(&pdev->dev, "Can't find acceleration device\n");
+ return PCI_ERS_RESULT_DISCONNECT;
+ }
+
+ if (!adf_devmgr_in_reset(accel_dev))
+ goto reset_complete;
+
+ pci_restore_state(pdev);
+ res = adf_dev_up(accel_dev, false);
+ if (res && res != -EALREADY)
+ return PCI_ERS_RESULT_DISCONNECT;
+
+ adf_reenable_sriov(accel_dev);
+ adf_pf2vf_notify_restarted(accel_dev);
+ adf_dev_restarted_notify(accel_dev);
+ clear_bit(ADF_STATUS_RESTARTING, &accel_dev->status);
+
+reset_complete:
+ dev_info(&pdev->dev, "Device reset completed successfully\n");
+
+ return PCI_ERS_RESULT_RECOVERED;
+}
+
+static pci_ers_result_t adf_error_detected(struct pci_dev *pdev,
+ pci_channel_state_t state)
+{
+ struct adf_accel_dev *accel_dev = adf_devmgr_pci_to_accel_dev(pdev);
+
+ dev_info(&pdev->dev, "Acceleration driver hardware error detected.\n");
+ if (!accel_dev) {
+ dev_err(&pdev->dev, "Can't find acceleration device\n");
+ return PCI_ERS_RESULT_DISCONNECT;
+ }
+
+ if (state == pci_channel_io_perm_failure) {
+ dev_err(&pdev->dev, "Can't recover from device error\n");
+ return PCI_ERS_RESULT_DISCONNECT;
+ }
+
+ adf_error_notifier(accel_dev);
+ adf_pf2vf_notify_fatal_error(accel_dev);
+
+ return reset_prepare(pdev);
+}
+
/* reset dev data */
struct adf_reset_dev_data {
int mode;
static pci_ers_result_t adf_slot_reset(struct pci_dev *pdev)
{
- struct adf_accel_dev *accel_dev = adf_devmgr_pci_to_accel_dev(pdev);
- int res = 0;
-
- if (!accel_dev) {
- pr_err("QAT: Can't find acceleration device\n");
- return PCI_ERS_RESULT_DISCONNECT;
- }
-
- if (!adf_devmgr_in_reset(accel_dev))
- goto reset_complete;
-
- pci_restore_state(pdev);
- res = adf_dev_up(accel_dev, false);
- if (res && res != -EALREADY)
- return PCI_ERS_RESULT_DISCONNECT;
-
- adf_reenable_sriov(accel_dev);
- adf_pf2vf_notify_restarted(accel_dev);
- adf_dev_restarted_notify(accel_dev);
- clear_bit(ADF_STATUS_RESTARTING, &accel_dev->status);
-
-reset_complete:
- return PCI_ERS_RESULT_RECOVERED;
+ return reset_done(pdev);
}
static void adf_resume(struct pci_dev *pdev)