These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / acpi / acpica / utids.c
index 27431cf..7956df1 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Module Name: utids - support for device Ids - HID, UID, CID
+ * Module Name: utids - support for device Ids - HID, UID, CID, SUB, CLS
  *
  *****************************************************************************/
 
@@ -111,7 +111,7 @@ acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
        if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
                acpi_ex_eisa_id_to_string(hid->string, obj_desc->integer.value);
        } else {
-               ACPI_STRCPY(hid->string, obj_desc->string.pointer);
+               strcpy(hid->string, obj_desc->string.pointer);
        }
 
        hid->length = length;
@@ -180,7 +180,7 @@ acpi_ut_execute_SUB(struct acpi_namespace_node *device_node,
 
        /* Simply copy existing string */
 
-       ACPI_STRCPY(sub->string, obj_desc->string.pointer);
+       strcpy(sub->string, obj_desc->string.pointer);
        sub->length = length;
        *return_id = sub;
 
@@ -256,7 +256,7 @@ acpi_ut_execute_UID(struct acpi_namespace_node *device_node,
        if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
                acpi_ex_integer_to_string(uid->string, obj_desc->integer.value);
        } else {
-               ACPI_STRCPY(uid->string, obj_desc->string.pointer);
+               strcpy(uid->string, obj_desc->string.pointer);
        }
 
        uid->length = length;
@@ -393,8 +393,7 @@ acpi_ut_execute_CID(struct acpi_namespace_node *device_node,
 
                        /* Copy the String CID from the returned object */
 
-                       ACPI_STRCPY(next_id_string,
-                                   cid_objects[i]->string.pointer);
+                       strcpy(next_id_string, cid_objects[i]->string.pointer);
                        length = cid_objects[i]->string.length + 1;
                }
 
@@ -416,3 +415,92 @@ cleanup:
        acpi_ut_remove_reference(obj_desc);
        return_ACPI_STATUS(status);
 }
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_execute_CLS
+ *
+ * PARAMETERS:  device_node         - Node for the device
+ *              return_id           - Where the _CLS is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Executes the _CLS control method that returns PCI-defined
+ *              class code of the device. The _CLS value is always a package
+ *              containing PCI class information as a list of integers.
+ *              The returned string has format "BBSSPP", where:
+ *                BB = Base-class code
+ *                SS = Sub-class code
+ *                PP = Programming Interface code
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_execute_CLS(struct acpi_namespace_node *device_node,
+                   struct acpi_pnp_device_id **return_id)
+{
+       union acpi_operand_object *obj_desc;
+       union acpi_operand_object **cls_objects;
+       u32 count;
+       struct acpi_pnp_device_id *cls;
+       u32 length;
+       acpi_status status;
+       u8 class_code[3] = { 0, 0, 0 };
+
+       ACPI_FUNCTION_TRACE(ut_execute_CLS);
+
+       status = acpi_ut_evaluate_object(device_node, METHOD_NAME__CLS,
+                                        ACPI_BTYPE_PACKAGE, &obj_desc);
+       if (ACPI_FAILURE(status)) {
+               return_ACPI_STATUS(status);
+       }
+
+       /* Get the size of the String to be returned, includes null terminator */
+
+       length = ACPI_PCICLS_STRING_SIZE;
+       cls_objects = obj_desc->package.elements;
+       count = obj_desc->package.count;
+
+       if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
+               if (count > 0
+                   && cls_objects[0]->common.type == ACPI_TYPE_INTEGER) {
+                       class_code[0] = (u8)cls_objects[0]->integer.value;
+               }
+               if (count > 1
+                   && cls_objects[1]->common.type == ACPI_TYPE_INTEGER) {
+                       class_code[1] = (u8)cls_objects[1]->integer.value;
+               }
+               if (count > 2
+                   && cls_objects[2]->common.type == ACPI_TYPE_INTEGER) {
+                       class_code[2] = (u8)cls_objects[2]->integer.value;
+               }
+       }
+
+       /* Allocate a buffer for the CLS */
+
+       cls =
+           ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pnp_device_id) +
+                                (acpi_size) length);
+       if (!cls) {
+               status = AE_NO_MEMORY;
+               goto cleanup;
+       }
+
+       /* Area for the string starts after PNP_DEVICE_ID struct */
+
+       cls->string =
+           ACPI_ADD_PTR(char, cls, sizeof(struct acpi_pnp_device_id));
+
+       /* Simply copy existing string */
+
+       acpi_ex_pci_cls_to_string(cls->string, class_code);
+       cls->length = length;
+       *return_id = cls;
+
+cleanup:
+
+       /* On exit, we must delete the return object */
+
+       acpi_ut_remove_reference(obj_desc);
+       return_ACPI_STATUS(status);
+}