drivers/net/wireless/intel/iwlwifi/fw/acpi.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/intel/iwlwifi/fw/acpi.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/intel/iwlwifi/fw/acpi.c
Extension
.c
Size
30722 bytes
Lines
1231
Domain
Driver Families
Bucket
drivers/net
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

if (WARN_ON_ONCE(expected_size > sizeof(le_value))) {
			ret = -EINVAL;
			goto out;
		}

		/* if the buffer size doesn't match the expected size */
		if (obj->buffer.length != expected_size)
			IWL_DEBUG_DEV_RADIO(dev,
					    "ACPI: DSM invalid buffer size, padding or truncating (%d)\n",
					    obj->buffer.length);

		 /* assuming LE from Intel BIOS spec */
		memcpy(&le_value, obj->buffer.pointer,
		       min_t(size_t, expected_size, (size_t)obj->buffer.length));
		*value = le64_to_cpu(le_value);
	} else {
		IWL_DEBUG_DEV_RADIO(dev,
				    "ACPI: DSM method did not return a valid object, type=%d\n",
				    obj->type);
		ret = -EINVAL;
		goto out;
	}

	IWL_DEBUG_DEV_RADIO(dev,
			    "ACPI: DSM method evaluated: func=%d, value=%lld\n",
			    func, *value);
	ret = 0;
out:
	ACPI_FREE(obj);
	return ret;
}

/*
 * This function loads all the DSM functions, it checks the size and populates
 * the cache with the values in a 32-bit field.
 * In case the expected size is smaller than 32-bit, padding will be added.
 */
static int iwl_acpi_load_dsm_values(struct iwl_fw_runtime *fwrt)
{
	u64 query_func_val;
	int ret;

	BUILD_BUG_ON(ARRAY_SIZE(acpi_dsm_size) != DSM_FUNC_NUM_FUNCS);

	ret = iwl_acpi_get_dsm_integer(fwrt->dev, ACPI_DSM_REV,
				       DSM_FUNC_QUERY,
				       &iwl_guid, &query_func_val,
				       acpi_dsm_size[DSM_FUNC_QUERY]);

	if (ret) {
		IWL_DEBUG_RADIO(fwrt, "ACPI QUERY FUNC not valid: %d\n", ret);
		return ret;
	}

	fwrt->dsm_revision = ACPI_DSM_REV;
	fwrt->dsm_source = BIOS_SOURCE_ACPI;

	IWL_DEBUG_RADIO(fwrt, "ACPI DSM validity bitmap 0x%x\n",
			(u32)query_func_val);

	/* DSM_FUNC_QUERY is 0, start from 1 */
	for (int func = 1; func < ARRAY_SIZE(fwrt->dsm_values); func++) {
		size_t expected_size = acpi_dsm_size[func];
		u64 tmp;

		if (!(query_func_val & BIT(func))) {
			IWL_DEBUG_RADIO(fwrt,
					"ACPI DSM %d not indicated as valid\n",
					func);
			continue;
		}

		/* This is an invalid function (5 for example) */
		if (!expected_size)
			continue;

		/* Currently all ACPI DSMs are either 8-bit or 32-bit */
		if (expected_size != sizeof(u8) && expected_size != sizeof(u32))
			continue;

		ret = iwl_acpi_get_dsm_integer(fwrt->dev, ACPI_DSM_REV, func,
					       &iwl_guid, &tmp, expected_size);
		if (ret)
			continue;

		if ((expected_size == sizeof(u8) && tmp != (u8)tmp) ||
		    (expected_size == sizeof(u32) && tmp != (u32)tmp))
			IWL_DEBUG_RADIO(fwrt,
					"DSM value overflows the expected size, truncating\n");
		fwrt->dsm_values[func] = (u32)tmp;

Annotation

Implementation Notes