drivers/crypto/intel/qat/qat_common/adf_aer.c

Source file repositories/reference/linux-study-clean/drivers/crypto/intel/qat/qat_common/adf_aer.c

File Facts

System
Linux kernel
Corpus path
drivers/crypto/intel/qat/qat_common/adf_aer.c
Extension
.c
Size
9038 bytes
Lines
343
Domain
Driver Families
Bucket
drivers/crypto
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct adf_fatal_error_data {
	struct adf_accel_dev *accel_dev;
	struct work_struct work;
};

static struct workqueue_struct *device_reset_wq;
static struct workqueue_struct *device_sriov_wq;

static pci_ers_result_t reset_prepare(struct pci_dev *pdev)
{
	struct adf_accel_dev *accel_dev = adf_devmgr_pci_to_accel_dev(pdev);

	if (!accel_dev) {
		pci_err(pdev, "Can't find acceleration device\n");
		return PCI_ERS_RESULT_DISCONNECT;
	}

	if (!adf_dev_started(accel_dev))
		return PCI_ERS_RESULT_CAN_RECOVER;

	set_bit(ADF_STATUS_RESTARTING, &accel_dev->status);
	if (accel_dev->hw_device->exit_arb) {
		dev_dbg(&pdev->dev, "Disabling arbitration\n");
		accel_dev->hw_device->exit_arb(accel_dev);
	}
	adf_dev_restarting_notify(accel_dev);
	adf_dev_down(accel_dev);

	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) {
		pci_err(pdev, "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:
	pci_info(pdev, "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);

	pci_info(pdev, "Acceleration driver hardware error detected.\n");
	if (!accel_dev) {
		pci_err(pdev, "Can't find acceleration device\n");
		return PCI_ERS_RESULT_DISCONNECT;
	}

	if (state == pci_channel_io_perm_failure) {
		pci_err(pdev, "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;
	struct adf_accel_dev *accel_dev;
	struct completion compl;
	struct work_struct reset_work;
};

Annotation

Implementation Notes