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 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 39 DeviceACPI::DeviceACPI(Device* parent) 40 : 41 Device(parent) 42 { 43 } 44 45 46 DeviceACPI::~DeviceACPI() 47 { 48 } 49 50 51 void 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 119 120 Attributes 121 DeviceACPI::GetBusAttributes() 122 { 123 // Push back things that matter for ACPI 124 Attributes attributes; 125 attributes.push_back(GetAttribute("device/bus")); 126 attributes.push_back(GetAttribute("acpi/path")); 127 attributes.push_back(GetAttribute("acpi/type")); 128 return attributes; 129 } 130 131 132 BString 133 DeviceACPI::GetBusStrings() 134 { 135 BString str(B_TRANSLATE("Class Info:\t\t\t\t: %classInfo%")); 136 str.ReplaceFirst("%classInfo%", fAttributeMap["Class Info"]); 137 138 return str; 139 } 140 141 142 BString 143 DeviceACPI::GetBusTabName() 144 { 145 return B_TRANSLATE("ACPI Information"); 146 } 147 148