1 /*
2 * Copyright 2008-2022 Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 * Rob Gill <rrobgill@protonmail.com>
7 * Alexander von Gluck (kallisti5)
8 */
9
10
11 #include "DeviceACPI.h"
12
13 #include <sstream>
14 #include <stdlib.h>
15
16 #include <Catalog.h>
17
18 extern "C" {
19 #include "acpipnpids.h"
20 }
21
22 #undef B_TRANSLATION_CONTEXT
23 #define B_TRANSLATION_CONTEXT "DeviceACPI"
24
25
26 void
acpi_get_vendor_info(const char * vendorID,const char ** vendorName)27 acpi_get_vendor_info(const char* vendorID, const char **vendorName)
28 {
29 for (size_t i = 0; i < ACPIPNP_DEVTABLE_LEN; i++) {
30 if (strncmp(acpipnp_devids[i].VenId, vendorID, strlen(acpipnp_devids[i].VenId)) == 0) {
31 *vendorName = acpipnp_devids[i].VenName;
32 return;
33 }
34 }
35 *vendorName = NULL;
36 }
37
38
DeviceACPI(Device * parent)39 DeviceACPI::DeviceACPI(Device* parent)
40 :
41 Device(parent)
42 {
43 }
44
45
~DeviceACPI()46 DeviceACPI::~DeviceACPI()
47 {
48 }
49
50
51 void
InitFromAttributes()52 DeviceACPI::InitFromAttributes()
53 {
54 BString nodeACPIPath;
55 BString rootACPIPath;
56 BString nodeACPIHid;
57 BString deviceName;
58
59 rootACPIPath = nodeACPIPath = GetAttribute("acpi/path").fValue;
60 nodeACPIHid = GetAttribute("acpi/hid").fValue;
61
62 // Grab just the root node info
63 // We grab 6 characters to not identify sub nodes of root node
64 rootACPIPath.Truncate(6);
65 // Grab node leaf name
66 nodeACPIPath.Remove(0, nodeACPIPath.FindLast(".") + 1);
67
68 fCategory = (Category)CAT_ACPI;
69
70 // Identify Predefined root namespaces (ACPI Spec 4.0a, p162)
71 if (rootACPIPath == "\\_SB_") {
72 deviceName = B_TRANSLATE("ACPI System Bus");
73 } else if (rootACPIPath == "\\_TZ_") {
74 deviceName = B_TRANSLATE("ACPI Thermal Zone");
75 } else if (rootACPIPath == "\\_PR_.") {
76 // This allows to localize apostrophes, too
77 BString string(B_TRANSLATE("ACPI Processor Namespace '%2'"));
78 string.ReplaceFirst("%2", nodeACPIPath);
79 // each CPU node is considered a root node
80 deviceName << string.String();
81 } else if (rootACPIPath == "\\_SI_") {
82 deviceName = B_TRANSLATE("ACPI System Indicator");
83 } else if (nodeACPIPath != "") {
84 // This allows to localize apostrophes, too
85 BString string(B_TRANSLATE("ACPI node '%1'"));
86 string.ReplaceFirst("%1", nodeACPIPath);
87 deviceName << string.String();
88 } else if (nodeACPIPath == "" && nodeACPIHid != "") {
89 // Handle ACPI HID entries that do not return a path
90 nodeACPIHid.Remove(0, nodeACPIHid.FindLast("_") + 1);
91 BString string(B_TRANSLATE("ACPI Button '%1'"));
92 string.ReplaceFirst("%1", nodeACPIHid);
93 deviceName << string.String();
94 } else {
95 BString string(B_TRANSLATE("ACPI <unknown>"));
96 deviceName << string.String();
97 }
98
99 // Fetch ManufacturerName
100 const char* vendorName = NULL;
101 BString manufacturerLabel;
102 if (nodeACPIHid != "")
103 acpi_get_vendor_info(nodeACPIHid, &vendorName);
104 if (vendorName == NULL) {
105 manufacturerLabel << B_TRANSLATE("Unknown");
106 } else {
107 manufacturerLabel << vendorName;
108 };
109
110 SetAttribute(B_TRANSLATE("Device name"), deviceName.String());
111 SetAttribute(B_TRANSLATE("Manufacturer"), manufacturerLabel);
112 BString outlineName;
113 if (vendorName != NULL)
114 outlineName << vendorName << " ";
115 outlineName << deviceName;
116 SetText(outlineName.String());
117 }
118