drivers/infiniband/hw/mthca/mthca_main.c

Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/mthca/mthca_main.c

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/hw/mthca/mthca_main.c
Extension
.c
Size
34726 bytes
Lines
1258
Domain
Driver Families
Bucket
drivers/infiniband
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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

static struct pci_driver mthca_driver = {
	.name		= DRV_NAME,
	.id_table	= mthca_pci_table,
	.probe		= mthca_init_one,
	.remove		= mthca_remove_one,
};

static void __init __mthca_check_profile_val(const char *name, int *pval,
					     int pval_default)
{
	/* value must be positive and power of 2 */
	int old_pval = *pval;

	if (old_pval <= 0)
		*pval = pval_default;
	else
		*pval = roundup_pow_of_two(old_pval);

	if (old_pval != *pval) {
		printk(KERN_WARNING PFX "Invalid value %d for %s in module parameter.\n",
		       old_pval, name);
		printk(KERN_WARNING PFX "Corrected %s to %d.\n", name, *pval);
	}
}

#define mthca_check_profile_val(name, default)				\
	__mthca_check_profile_val(#name, &hca_profile.name, default)

static void __init mthca_validate_profile(void)
{
	mthca_check_profile_val(num_qp,            MTHCA_DEFAULT_NUM_QP);
	mthca_check_profile_val(rdb_per_qp,        MTHCA_DEFAULT_RDB_PER_QP);
	mthca_check_profile_val(num_cq,            MTHCA_DEFAULT_NUM_CQ);
	mthca_check_profile_val(num_mcg, 	   MTHCA_DEFAULT_NUM_MCG);
	mthca_check_profile_val(num_mpt, 	   MTHCA_DEFAULT_NUM_MPT);
	mthca_check_profile_val(num_mtt, 	   MTHCA_DEFAULT_NUM_MTT);
	mthca_check_profile_val(num_udav,          MTHCA_DEFAULT_NUM_UDAV);
	mthca_check_profile_val(fmr_reserved_mtts, MTHCA_DEFAULT_NUM_RESERVED_MTTS);

	if (hca_profile.fmr_reserved_mtts >= hca_profile.num_mtt) {
		printk(KERN_WARNING PFX "Invalid fmr_reserved_mtts module parameter %d.\n",
		       hca_profile.fmr_reserved_mtts);
		printk(KERN_WARNING PFX "(Must be smaller than num_mtt %d)\n",
		       hca_profile.num_mtt);
		hca_profile.fmr_reserved_mtts = hca_profile.num_mtt / 2;
		printk(KERN_WARNING PFX "Corrected fmr_reserved_mtts to %d.\n",
		       hca_profile.fmr_reserved_mtts);
	}

	if ((log_mtts_per_seg < 1) || (log_mtts_per_seg > 5)) {
		printk(KERN_WARNING PFX "bad log_mtts_per_seg (%d). Using default - %d\n",
		       log_mtts_per_seg, ilog2(MTHCA_MTT_SEG_SIZE / 8));
		log_mtts_per_seg = ilog2(MTHCA_MTT_SEG_SIZE / 8);
	}
}

static int __init mthca_init(void)
{
	int ret;

	mthca_validate_profile();

	ret = mthca_catas_init();
	if (ret)
		return ret;

	ret = pci_register_driver(&mthca_driver);
	if (ret < 0) {
		mthca_catas_cleanup();
		return ret;
	}

	return 0;
}

static void __exit mthca_cleanup(void)
{
	pci_unregister_driver(&mthca_driver);
	mthca_catas_cleanup();
}

module_init(mthca_init);
module_exit(mthca_cleanup);

Annotation

Implementation Notes