static int
dsm_get_label(acpi_handle handle, int func,
	      struct acpi_buffer *output,
	      char *buf, enum acpi_attr_enum attribute)
{
	struct acpi_object_list input;
	union acpi_object params[4];
	union acpi_object *obj;
	int len = 0;

	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)
		return -1;

	obj = (union acpi_object *)output->pointer;

	switch (obj->type) {
	case ACPI_TYPE_PACKAGE:
		if (obj->package.count != 2)
			break;
		len = obj->package.elements[0].integer.value;
		if (buf) {
			if (attribute == 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);
		}
		kfree(output->pointer);
		return len;
	break;
	default:
		kfree(output->pointer);
	}
	return -1;
}
Example #2
0
static int dsm_get_label(struct device *dev, char *buf,
			 enum acpi_attr_enum attr)
{
	acpi_handle handle;
	union acpi_object *obj, *tmp;
	int len = -1;

	handle = ACPI_HANDLE(dev);
	if (!handle)
		return -1;

	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 ||
	     tmp[1].type == ACPI_TYPE_BUFFER)) {
		/*
		 * The 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", tmp->integer.value);
		} else if (attr == ACPI_ATTR_LABEL_SHOW) {
			if (tmp[1].type == ACPI_TYPE_STRING)
				scnprintf(buf, PAGE_SIZE, "%s\n",
					  tmp[1].string.pointer);
			else if (tmp[1].type == ACPI_TYPE_BUFFER)
				dsm_label_utf16s_to_utf8s(tmp + 1, buf);
		}
		len = strlen(buf) > 0 ? strlen(buf) : -1;
	}

	ACPI_FREE(obj);

	return len;
}