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

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

File Facts

System
Linux kernel
Corpus path
drivers/crypto/intel/qat/qat_common/adf_isr.c
Extension
.c
Size
12160 bytes
Lines
455
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

for_each_set_bit(i, &vf_mask, ADF_MAX_NUM_VFS) {
			vf_info = accel_dev->pf.vf_info + i;

			if (!__ratelimit(&vf_info->vf2pf_ratelimit)) {
				dev_info(&GET_DEV(accel_dev),
					 "Too many ints from VF%d\n",
					  vf_info->vf_nr);
				continue;
			}

			adf_schedule_vf2pf_handler(vf_info);
			irq_handled = true;
		}
	}
	return irq_handled;
}
#endif /* CONFIG_PCI_IOV */

static bool adf_handle_pm_int(struct adf_accel_dev *accel_dev)
{
	struct adf_hw_device_data *hw_data = accel_dev->hw_device;

	if (hw_data->handle_pm_interrupt &&
	    hw_data->handle_pm_interrupt(accel_dev))
		return true;

	return false;
}

static bool adf_handle_ras_int(struct adf_accel_dev *accel_dev)
{
	struct adf_ras_ops *ras_ops = &accel_dev->hw_device->ras_ops;
	bool reset_required;

	if (ras_ops->handle_interrupt &&
	    ras_ops->handle_interrupt(accel_dev, &reset_required)) {
		if (reset_required) {
			dev_err(&GET_DEV(accel_dev), "Fatal error, reset required\n");
			if (adf_notify_fatal_error(accel_dev))
				dev_err(&GET_DEV(accel_dev),
					"Failed to notify fatal error\n");
		}

		return true;
	}

	return false;
}

static irqreturn_t adf_msix_isr_ae(int irq, void *dev_ptr)
{
	struct adf_accel_dev *accel_dev = dev_ptr;

#ifdef CONFIG_PCI_IOV
	/* If SR-IOV is enabled (vf_info is non-NULL), check for VF->PF ints */
	if (accel_dev->pf.vf_info && adf_handle_vf2pf_int(accel_dev))
		return IRQ_HANDLED;
#endif /* CONFIG_PCI_IOV */

	if (adf_handle_pm_int(accel_dev))
		return IRQ_HANDLED;

	if (adf_handle_ras_int(accel_dev))
		return IRQ_HANDLED;

	dev_dbg(&GET_DEV(accel_dev), "qat_dev%d spurious AE interrupt\n",
		accel_dev->accel_id);

	return IRQ_NONE;
}

void adf_isr_sync_ae_cluster(struct adf_accel_dev *accel_dev)
{
	struct adf_accel_pci *pci_dev_info = &accel_dev->accel_pci_dev;
	struct adf_hw_device_data *hw_data = GET_HW_DATA(accel_dev);
	u32 num_entries = pci_dev_info->msix_entries.num_entries;
	struct adf_irq *irqs = pci_dev_info->msix_entries.irqs;
	u32 irq_idx;
	int irq;

	if (!test_bit(ADF_STATUS_IRQ_ALLOCATED, &accel_dev->status) || !irqs)
		return;

	irq_idx = num_entries > 1 ? hw_data->num_banks : 0;
	if (irq_idx >= num_entries || !irqs[irq_idx].enabled)
		return;

	irq = pci_irq_vector(pci_dev_info->pci_dev, hw_data->num_banks);
	if (irq > 0)
		synchronize_irq(irq);

Annotation

Implementation Notes