drivers/scsi/fnic/fnic_isr.c

Source file repositories/reference/linux-study-clean/drivers/scsi/fnic/fnic_isr.c

File Facts

System
Linux kernel
Corpus path
drivers/scsi/fnic/fnic_isr.c
Extension
.c
Size
10649 bytes
Lines
397
Domain
Driver Families
Bucket
drivers/scsi
Inferred role
Driver Families: implementation source
Status
source 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

if (err) {
				FNIC_ISR_DBG(KERN_ERR, fnic->host, fnic->fnic_num,
							"request_irq failed with error: %d\n",
							err);
				fnic_free_intr(fnic);
				break;
			}
			fnic->msix[i].requested = 1;
		}
		break;

	default:
		break;
	}

	return err;
}

int fnic_set_intr_mode_msix(struct fnic *fnic)
{
	unsigned int n = ARRAY_SIZE(fnic->rq);
	unsigned int m = ARRAY_SIZE(fnic->wq);
	unsigned int o = ARRAY_SIZE(fnic->hw_copy_wq);
	unsigned int min_irqs = n + m + 1 + 1; /*rq, raw wq, wq, err*/

	/*
	 * We need n RQs, m WQs, o Copy WQs, n+m+o CQs, and n+m+o+1 INTRs
	 * (last INTR is used for WQ/RQ errors and notification area)
	 */
	FNIC_ISR_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
		"rq-array size: %d wq-array size: %d copy-wq array size: %d\n",
		n, m, o);
	FNIC_ISR_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
		"rq_count: %d raw_wq_count: %d wq_copy_count: %d cq_count: %d\n",
		fnic->rq_count, fnic->raw_wq_count,
		fnic->wq_copy_count, fnic->cq_count);

	if (fnic->rq_count <= n && fnic->raw_wq_count <= m &&
		fnic->wq_copy_count <= o) {
		int vec_count = 0;
		int vecs = fnic->rq_count + fnic->raw_wq_count + fnic->wq_copy_count + 1;

		vec_count = pci_alloc_irq_vectors(fnic->pdev, min_irqs, vecs,
					PCI_IRQ_MSIX | PCI_IRQ_AFFINITY);
		FNIC_ISR_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
					"allocated %d MSI-X vectors\n",
					vec_count);

		if (vec_count > 0) {
			if (vec_count < vecs) {
				FNIC_ISR_DBG(KERN_ERR, fnic->host, fnic->fnic_num,
				"interrupts number mismatch: vec_count: %d vecs: %d\n",
				vec_count, vecs);
				if (vec_count < min_irqs) {
					FNIC_ISR_DBG(KERN_ERR, fnic->host, fnic->fnic_num,
								"no interrupts for copy wq\n");
					return 1;
				}
			}

			fnic->rq_count = n;
			fnic->raw_wq_count = m;
			fnic->copy_wq_base = fnic->rq_count + fnic->raw_wq_count;
			fnic->wq_copy_count = vec_count - n - m - 1;
			fnic->wq_count = fnic->raw_wq_count + fnic->wq_copy_count;
			if (fnic->cq_count != vec_count - 1) {
				FNIC_ISR_DBG(KERN_ERR, fnic->host, fnic->fnic_num,
				"CQ count: %d does not match MSI-X vector count: %d\n",
				fnic->cq_count, vec_count);
				fnic->cq_count = vec_count - 1;
			}
			fnic->intr_count = vec_count;
			fnic->err_intr_offset = fnic->rq_count + fnic->wq_count;

			FNIC_ISR_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
				"rq_count: %d raw_wq_count: %d copy_wq_base: %d\n",
				fnic->rq_count,
				fnic->raw_wq_count, fnic->copy_wq_base);

			FNIC_ISR_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
				"wq_copy_count: %d wq_count: %d cq_count: %d\n",
				fnic->wq_copy_count,
				fnic->wq_count, fnic->cq_count);

			FNIC_ISR_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
				"intr_count: %d err_intr_offset: %u",
				fnic->intr_count,
				fnic->err_intr_offset);

			vnic_dev_set_intr_mode(fnic->vdev, VNIC_DEV_INTR_MODE_MSIX);

Annotation

Implementation Notes