mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	ACPI / PCI: replace open-coded _DSM code with helper functions
Use helper functions to simplify _DSM related code in pci-label driver. Also enforce more strict checks on objects returned by _DSM method. Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
		
							parent
							
								
									54e5bb4659
								
							
						
					
					
						commit
						1d0fcef732
					
				
					 1 changed files with 33 additions and 86 deletions
				
			
		| 
						 | 
				
			
			@ -195,80 +195,58 @@ enum acpi_attr_enum {
 | 
			
		|||
static void dsm_label_utf16s_to_utf8s(union acpi_object *obj, char *buf)
 | 
			
		||||
{
 | 
			
		||||
	int len;
 | 
			
		||||
	len = utf16s_to_utf8s((const wchar_t *)obj->
 | 
			
		||||
			      package.elements[1].string.pointer,
 | 
			
		||||
			      obj->package.elements[1].string.length,
 | 
			
		||||
	len = utf16s_to_utf8s((const wchar_t *)obj->string.pointer,
 | 
			
		||||
			      obj->string.length,
 | 
			
		||||
			      UTF16_LITTLE_ENDIAN,
 | 
			
		||||
			      buf, PAGE_SIZE);
 | 
			
		||||
	buf[len] = '\n';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
dsm_get_label(acpi_handle handle, int func,
 | 
			
		||||
	      struct acpi_buffer *output,
 | 
			
		||||
	      char *buf, enum acpi_attr_enum attribute)
 | 
			
		||||
dsm_get_label(struct device *dev, char *buf, enum acpi_attr_enum attr)
 | 
			
		||||
{
 | 
			
		||||
	struct acpi_object_list input;
 | 
			
		||||
	union acpi_object params[4];
 | 
			
		||||
	union acpi_object *obj;
 | 
			
		||||
	int len = 0;
 | 
			
		||||
	acpi_handle handle;
 | 
			
		||||
	union acpi_object *obj, *tmp;
 | 
			
		||||
	int len = -1;
 | 
			
		||||
 | 
			
		||||
	int err;
 | 
			
		||||
 | 
			
		||||
	input.count = 4;
 | 
			
		||||
	input.pointer = params;
 | 
			
		||||
	params[0].type = ACPI_TYPE_BUFFER;
 | 
			
		||||
	params[0].buffer.length = sizeof(device_label_dsm_uuid);
 | 
			
		||||
	params[0].buffer.pointer = (char *)device_label_dsm_uuid;
 | 
			
		||||
	params[1].type = ACPI_TYPE_INTEGER;
 | 
			
		||||
	params[1].integer.value = 0x02;
 | 
			
		||||
	params[2].type = ACPI_TYPE_INTEGER;
 | 
			
		||||
	params[2].integer.value = func;
 | 
			
		||||
	params[3].type = ACPI_TYPE_PACKAGE;
 | 
			
		||||
	params[3].package.count = 0;
 | 
			
		||||
	params[3].package.elements = NULL;
 | 
			
		||||
 | 
			
		||||
	err = acpi_evaluate_object(handle, "_DSM", &input, output);
 | 
			
		||||
	if (err)
 | 
			
		||||
	handle = ACPI_HANDLE(dev);
 | 
			
		||||
	if (!handle)
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	obj = (union acpi_object *)output->pointer;
 | 
			
		||||
	if (obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 2) {
 | 
			
		||||
		len = obj->package.elements[0].integer.value;
 | 
			
		||||
	obj = acpi_evaluate_dsm(handle, device_label_dsm_uuid, 0x2,
 | 
			
		||||
				DEVICE_LABEL_DSM, NULL);
 | 
			
		||||
	if (!obj)
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	tmp = obj->package.elements;
 | 
			
		||||
	if (obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 2 &&
 | 
			
		||||
	    tmp[0].type == ACPI_TYPE_INTEGER &&
 | 
			
		||||
	    tmp[1].type == ACPI_TYPE_STRING) {
 | 
			
		||||
		len = tmp[0].integer.value;
 | 
			
		||||
		if (buf) {
 | 
			
		||||
			if (attribute == ACPI_ATTR_INDEX_SHOW)
 | 
			
		||||
			/*
 | 
			
		||||
			 * This second string element is optional even when
 | 
			
		||||
			 * this _DSM is implemented; when not implemented,
 | 
			
		||||
			 * this entry must return a null string.
 | 
			
		||||
			 */
 | 
			
		||||
			if (attr == ACPI_ATTR_INDEX_SHOW)
 | 
			
		||||
				scnprintf(buf, PAGE_SIZE, "%llu\n",
 | 
			
		||||
				obj->package.elements[0].integer.value);
 | 
			
		||||
			else if (attribute == ACPI_ATTR_LABEL_SHOW)
 | 
			
		||||
				dsm_label_utf16s_to_utf8s(obj, buf);
 | 
			
		||||
			kfree(output->pointer);
 | 
			
		||||
			return strlen(buf);
 | 
			
		||||
				tmp->integer.value);
 | 
			
		||||
			else if (attr == ACPI_ATTR_LABEL_SHOW)
 | 
			
		||||
				dsm_label_utf16s_to_utf8s(tmp + 1, buf);
 | 
			
		||||
			len = strlen(buf) > 0 ? strlen(buf) : -1;
 | 
			
		||||
		}
 | 
			
		||||
		kfree(output->pointer);
 | 
			
		||||
		return len;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	kfree(output->pointer);
 | 
			
		||||
	ACPI_FREE(obj);
 | 
			
		||||
 | 
			
		||||
	return -1;
 | 
			
		||||
	return len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool
 | 
			
		||||
device_has_dsm(struct device *dev)
 | 
			
		||||
{
 | 
			
		||||
	acpi_handle handle;
 | 
			
		||||
	struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
 | 
			
		||||
 | 
			
		||||
	handle = ACPI_HANDLE(dev);
 | 
			
		||||
 | 
			
		||||
	if (!handle)
 | 
			
		||||
		return FALSE;
 | 
			
		||||
 | 
			
		||||
	if (dsm_get_label(handle, DEVICE_LABEL_DSM, &output, NULL,
 | 
			
		||||
			  ACPI_ATTR_NONE) > 0)
 | 
			
		||||
		return TRUE;
 | 
			
		||||
 | 
			
		||||
	return FALSE;
 | 
			
		||||
	return dsm_get_label(dev, NULL, ACPI_ATTR_NONE) > 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static umode_t
 | 
			
		||||
| 
						 | 
				
			
			@ -287,44 +265,13 @@ acpi_index_string_exist(struct kobject *kobj, struct attribute *attr, int n)
 | 
			
		|||
static ssize_t
 | 
			
		||||
acpilabel_show(struct device *dev, struct device_attribute *attr, char *buf)
 | 
			
		||||
{
 | 
			
		||||
	struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
 | 
			
		||||
	acpi_handle handle;
 | 
			
		||||
	int length;
 | 
			
		||||
 | 
			
		||||
	handle = ACPI_HANDLE(dev);
 | 
			
		||||
 | 
			
		||||
	if (!handle)
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	length = dsm_get_label(handle, DEVICE_LABEL_DSM,
 | 
			
		||||
			       &output, buf, ACPI_ATTR_LABEL_SHOW);
 | 
			
		||||
 | 
			
		||||
	if (length < 1)
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	return length;
 | 
			
		||||
	return dsm_get_label(dev, buf, ACPI_ATTR_LABEL_SHOW);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ssize_t
 | 
			
		||||
acpiindex_show(struct device *dev, struct device_attribute *attr, char *buf)
 | 
			
		||||
{
 | 
			
		||||
	struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
 | 
			
		||||
	acpi_handle handle;
 | 
			
		||||
	int length;
 | 
			
		||||
 | 
			
		||||
	handle = ACPI_HANDLE(dev);
 | 
			
		||||
 | 
			
		||||
	if (!handle)
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	length = dsm_get_label(handle, DEVICE_LABEL_DSM,
 | 
			
		||||
			       &output, buf, ACPI_ATTR_INDEX_SHOW);
 | 
			
		||||
 | 
			
		||||
	if (length < 0)
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	return length;
 | 
			
		||||
 | 
			
		||||
	return dsm_get_label(dev, buf, ACPI_ATTR_INDEX_SHOW);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct device_attribute acpi_attr_label = {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue