drivers/pci/endpoint/functions/pci-epf-vntb.c

Source file repositories/reference/linux-study-clean/drivers/pci/endpoint/functions/pci-epf-vntb.c

File Facts

System
Linux kernel
Corpus path
drivers/pci/endpoint/functions/pci-epf-vntb.c
Extension
.c
Size
43382 bytes
Lines
1679
Domain
Representative Device Path
Bucket
PCIe NVMe Storage Path
Inferred role
Representative Device Path: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.

Dependency Surface

Detected Declarations

Annotated Snippet

static struct pci_driver vntb_pci_driver = {
	.name           = "pci-vntb",
	.id_table       = pci_vntb_table,
	.probe          = pci_vntb_probe,
};

/* ============ PCIe EPF Driver Bind ====================*/

/**
 * epf_ntb_bind() - Initialize endpoint controller to provide NTB functionality
 * @epf: NTB endpoint function device
 *
 * Initialize both the endpoint controllers associated with NTB function device.
 * Invoked when a primary interface or secondary interface is bound to EPC
 * device. This function will succeed only when EPC is bound to both the
 * interfaces.
 *
 * Returns: Zero for success, or an error code in case of failure
 */
static int epf_ntb_bind(struct pci_epf *epf)
{
	struct epf_ntb *ntb = epf_get_drvdata(epf);
	struct device *dev = &epf->dev;
	int ret;

	if (!epf->epc) {
		dev_dbg(dev, "PRIMARY EPC interface not yet bound\n");
		return 0;
	}

	ret = epf_ntb_init_epc_bar(ntb);
	if (ret) {
		dev_err(dev, "Failed to create NTB EPC\n");
		return ret;
	}

	ret = epf_ntb_config_spad_bar_alloc(ntb);
	if (ret) {
		dev_err(dev, "Failed to allocate BAR memory\n");
		goto err_bar_alloc;
	}

	ret = epf_ntb_epc_init(ntb);
	if (ret) {
		dev_err(dev, "Failed to initialize EPC\n");
		goto err_bar_alloc;
	}

	epf_set_drvdata(epf, ntb);

	pci_space[0] = (ntb->vntb_pid << 16) | ntb->vntb_vid;
	pci_vntb_table[0].vendor = ntb->vntb_vid;
	pci_vntb_table[0].device = ntb->vntb_pid;

	ret = pci_register_driver(&vntb_pci_driver);
	if (ret) {
		dev_err(dev, "failure register vntb pci driver\n");
		goto err_epc_cleanup;
	}

	ret = vpci_scan_bus(ntb);
	if (ret)
		goto err_unregister;

	return 0;

err_unregister:
	pci_unregister_driver(&vntb_pci_driver);
err_epc_cleanup:
	epf_ntb_epc_cleanup(ntb);
err_bar_alloc:
	epf_ntb_config_spad_bar_free(ntb);

	return ret;
}

/**
 * epf_ntb_unbind() - Cleanup the initialization from epf_ntb_bind()
 * @epf: NTB endpoint function device
 *
 * Cleanup the initialization from epf_ntb_bind()
 */
static void epf_ntb_unbind(struct pci_epf *epf)
{
	struct epf_ntb *ntb = epf_get_drvdata(epf);

	epf_ntb_epc_cleanup(ntb);
	epf_ntb_config_spad_bar_free(ntb);

	pci_unregister_driver(&vntb_pci_driver);

Annotation

Implementation Notes