drivers/platform/x86/dell/dell-wmi-sysman/passobj-attributes.c

Source file repositories/reference/linux-study-clean/drivers/platform/x86/dell/dell-wmi-sysman/passobj-attributes.c

File Facts

System
Linux kernel
Corpus path
drivers/platform/x86/dell/dell-wmi-sysman/passobj-attributes.c
Extension
.c
Size
5326 bytes
Lines
199
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

// SPDX-License-Identifier: GPL-2.0
/*
 * Functions corresponding to password object type attributes under BIOS Password Object GUID for
 * use with dell-wmi-sysman
 *
 *  Copyright (c) 2020 Dell Inc.
 */

#include "dell-wmi-sysman.h"

enum po_properties {IS_PASS_SET = 1, MIN_PASS_LEN, MAX_PASS_LEN};

get_instance_id(po);

static ssize_t is_enabled_show(struct kobject *kobj, struct kobj_attribute *attr,
					  char *buf)
{
	int instance_id = get_po_instance_id(kobj);
	union acpi_object *obj;
	ssize_t ret;

	if (instance_id < 0)
		return instance_id;

	/* need to use specific instance_id and guid combination to get right data */
	obj = get_wmiobj_pointer(instance_id, DELL_WMI_BIOS_PASSOBJ_ATTRIBUTE_GUID);
	if (!obj)
		return -EIO;
	if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count < PO_MIN_ELEMENTS ||
	    obj->package.elements[IS_PASS_SET].type != ACPI_TYPE_INTEGER) {
		kfree(obj);
		return -EIO;
	}
	ret = snprintf(buf, PAGE_SIZE, "%lld\n", obj->package.elements[IS_PASS_SET].integer.value);
	kfree(obj);
	return ret;
}

static struct kobj_attribute po_is_pass_set = __ATTR_RO(is_enabled);

static ssize_t current_password_store(struct kobject *kobj,
				      struct kobj_attribute *attr,
				      const char *buf, size_t count)
{
	char *target = NULL;
	int length;

	length = strlen(buf);
	if (length && buf[length - 1] == '\n')
		length--;

	/* firmware does verifiation of min/max password length,
	 * hence only check for not exceeding MAX_BUFF here.
	 */
	if (length >= MAX_BUFF)
		return -EINVAL;

	if (strcmp(kobj->name, "Admin") == 0)
		target = wmi_priv.current_admin_password;
	else if (strcmp(kobj->name, "System") == 0)
		target = wmi_priv.current_system_password;
	if (!target)
		return -EIO;
	memcpy(target, buf, length);
	target[length] = '\0';

	return count;
}

static struct kobj_attribute po_current_password = __ATTR_WO(current_password);

static ssize_t new_password_store(struct kobject *kobj,
				  struct kobj_attribute *attr,
				  const char *buf, size_t count)
{
	char *p, *buf_cp;
	int ret;

	buf_cp = kstrdup(buf, GFP_KERNEL);
	if (!buf_cp)
		return -ENOMEM;
	p = memchr(buf_cp, '\n', count);

	if (p != NULL)
		*p = '\0';
	if (strlen(buf_cp) > MAX_BUFF) {
		ret = -EINVAL;
		goto out;
	}

Annotation

Implementation Notes