drivers/platform/x86/hp/hp-bioscfg/string-attributes.c

Source file repositories/reference/linux-study-clean/drivers/platform/x86/hp/hp-bioscfg/string-attributes.c

File Facts

System
Linux kernel
Corpus path
drivers/platform/x86/hp/hp-bioscfg/string-attributes.c
Extension
.c
Size
11002 bytes
Lines
392
Domain
Driver Families
Bucket
drivers/platform
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

switch (string_obj[elem].type) {
		case ACPI_TYPE_STRING:
			if (elem != PREREQUISITES) {
				ret = hp_convert_hexstr_to_str(string_obj[elem].string.pointer,
							       string_obj[elem].string.length,
							       &str_value, &value_len);

				if (ret)
					continue;
			}
			break;
		case ACPI_TYPE_INTEGER:
			int_value = (u32)string_obj[elem].integer.value;
			break;
		default:
			pr_warn("Unsupported object type [%d]\n", string_obj[elem].type);
			continue;
		}

		/* Check that both expected and read object type match */
		if (expected_string_types[eloc] != string_obj[elem].type) {
			pr_err("Error expected type %d for elem %d, but got type %d instead\n",
			       expected_string_types[eloc], elem, string_obj[elem].type);
			kfree(str_value);
			return -EIO;
		}

		/* Assign appropriate element value to corresponding field*/
		switch (eloc) {
		case VALUE:
			strscpy(string_data->current_value, str_value);
			break;
		case PATH:
			strscpy(string_data->common.path, str_value);
			break;
		case IS_READONLY:
			string_data->common.is_readonly = int_value;
			break;
		case DISPLAY_IN_UI:
			string_data->common.display_in_ui = int_value;
			break;
		case REQUIRES_PHYSICAL_PRESENCE:
			string_data->common.requires_physical_presence = int_value;
			break;
		case SEQUENCE:
			string_data->common.sequence = int_value;
			break;
		case PREREQUISITES_SIZE:
			if (int_value > MAX_PREREQUISITES_SIZE) {
				pr_warn("Prerequisites size value exceeded the maximum number of elements supported or data may be malformed\n");
				int_value = MAX_PREREQUISITES_SIZE;
			}
			string_data->common.prerequisites_size = int_value;

			/*
			 * This step is needed to keep the expected
			 * element list pointing to the right obj[elem].type
			 * when the size is zero. PREREQUISITES
			 * object is omitted by BIOS when the size is
			 * zero.
			 */
			if (string_data->common.prerequisites_size == 0)
				eloc++;
			break;
		case PREREQUISITES:
			size = min_t(u32, string_data->common.prerequisites_size,
				     MAX_PREREQUISITES_SIZE);

			for (reqs = 0; reqs < size; reqs++) {
				if (elem + reqs >= string_obj_count) {
					pr_err("Error elem-objects package is too small\n");
					return -EINVAL;
				}

				ret = hp_convert_hexstr_to_str(string_obj[elem + reqs].string.pointer,
							       string_obj[elem + reqs].string.length,
							       &str_value, &value_len);

				if (ret)
					continue;

				strscpy(string_data->common.prerequisites[reqs], str_value);
				kfree(str_value);
				str_value = NULL;
			}
			break;

		case SECURITY_LEVEL:
			string_data->common.security_level = int_value;
			break;

Annotation

Implementation Notes