drivers/infiniband/hw/hfi1/platform.c

Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/hfi1/platform.c

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/hw/hfi1/platform.c
Extension
.c
Size
27091 bytes
Lines
1036
Domain
Driver Families
Bucket
drivers/infiniband
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 (validate_scratch_checksum(dd)) {
			save_platform_config_fields(dd);
			return;
		}
	} else {
		ret = eprom_read_platform_config(dd,
						 (void **)&temp_platform_config,
						 &esize);
		if (!ret) {
			/* success */
			dd->platform_config.data = temp_platform_config;
			dd->platform_config.size = esize;
			return;
		}
	}
	dd_dev_err(dd,
		   "%s: Failed to get platform config, falling back to sub-optimal default file\n",
		   __func__);

	ret = request_firmware(&platform_config_file,
			       DEFAULT_PLATFORM_CONFIG_NAME,
			       &dd->pcidev->dev);
	if (ret) {
		dd_dev_err(dd,
			   "%s: No default platform config file found\n",
			   __func__);
		return;
	}

	/*
	 * Allocate separate memory block to store data and free firmware
	 * structure. This allows free_platform_config to treat EPROM and
	 * fallback configs in the same manner.
	 */
	dd->platform_config.data = kmemdup(platform_config_file->data,
					   platform_config_file->size,
					   GFP_KERNEL);
	dd->platform_config.size = platform_config_file->size;
	release_firmware(platform_config_file);
}

void free_platform_config(struct hfi1_devdata *dd)
{
	/* Release memory allocated for eprom or fallback file read. */
	kfree(dd->platform_config.data);
	dd->platform_config.data = NULL;
}

void get_port_type(struct hfi1_pportdata *ppd)
{
	int ret;
	u32 temp;

	ret = get_platform_config_field(ppd->dd, PLATFORM_CONFIG_PORT_TABLE, 0,
					PORT_TABLE_PORT_TYPE, &temp,
					4);
	if (ret) {
		ppd->port_type = PORT_TYPE_UNKNOWN;
		return;
	}
	ppd->port_type = temp;
}

int set_qsfp_tx(struct hfi1_pportdata *ppd, int on)
{
	u8 tx_ctrl_byte = on ? 0x0 : 0xF;
	int ret = 0;

	ret = qsfp_write(ppd, ppd->dd->hfi1_id, QSFP_TX_CTRL_BYTE_OFFS,
			 &tx_ctrl_byte, 1);
	/* we expected 1, so consider 0 an error */
	if (ret == 0)
		ret = -EIO;
	else if (ret == 1)
		ret = 0;
	return ret;
}

static int qual_power(struct hfi1_pportdata *ppd)
{
	u32 cable_power_class = 0, power_class_max = 0;
	u8 *cache = ppd->qsfp_info.cache;
	int ret = 0;

	ret = get_platform_config_field(
		ppd->dd, PLATFORM_CONFIG_SYSTEM_TABLE, 0,
		SYSTEM_TABLE_QSFP_POWER_CLASS_MAX, &power_class_max, 4);
	if (ret)
		return ret;

Annotation

Implementation Notes