diff options
author | phajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-28 19:08:14 +0000 |
---|---|---|
committer | phajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-28 19:08:14 +0000 |
commit | dfbff862ecd56bf8ca179e676cd55aaca7346189 (patch) | |
tree | 0ddbc181048bc900abff065c629391d37a7e9527 /content/gpu | |
parent | 9c6b19bd0fd8045914b1c0138333148a596c69a2 (diff) | |
download | chromium_src-dfbff862ecd56bf8ca179e676cd55aaca7346189.zip chromium_src-dfbff862ecd56bf8ca179e676cd55aaca7346189.tar.gz chromium_src-dfbff862ecd56bf8ca179e676cd55aaca7346189.tar.bz2 |
Linux: create a library loader code generator for dlopen and use it for libpci.
BUG=162733
Review URL: https://codereview.chromium.org/11415138
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@170010 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/gpu')
-rw-r--r-- | content/gpu/gpu_info_collector_linux.cc | 132 |
1 files changed, 21 insertions, 111 deletions
diff --git a/content/gpu/gpu_info_collector_linux.cc b/content/gpu/gpu_info_collector_linux.cc index c6f2c2b..d849cab 100644 --- a/content/gpu/gpu_info_collector_linux.cc +++ b/content/gpu/gpu_info_collector_linux.cc @@ -4,15 +4,9 @@ #include "content/gpu/gpu_info_collector.h" -#include <dlfcn.h> #include <X11/Xlib.h> #include <vector> -// TODO(phajdan.jr): Report problem upstream and make pci.h handle this. -extern "C" { -#include <pci/pci.h> -} - #include "base/command_line.h" #include "base/debug/trace_event.h" #include "base/file_util.h" @@ -23,6 +17,7 @@ extern "C" { #include "base/string_split.h" #include "base/string_tokenizer.h" #include "base/string_util.h" +#include "library_loaders/libpci.h" #include "third_party/libXNVCtrl/NVCtrl.h" #include "third_party/libXNVCtrl/NVCtrlLib.h" #include "ui/gl/gl_bindings.h" @@ -33,28 +28,6 @@ extern "C" { namespace { -// Define function types. -typedef pci_access* (*FT_pci_alloc)(); -typedef void (*FT_pci_init)(pci_access*); -typedef void (*FT_pci_cleanup)(pci_access*); -typedef void (*FT_pci_scan_bus)(pci_access*); -typedef void (*FT_pci_scan_bus)(pci_access*); -typedef int (*FT_pci_fill_info)(pci_dev*, int); -typedef char* (*FT_pci_lookup_name)(pci_access*, char*, int, int, ...); - -// This includes dynamically linked library handle and functions pointers from -// libpci. -struct PciInterface { - void* lib_handle; - - FT_pci_alloc pci_alloc; - FT_pci_init pci_init; - FT_pci_cleanup pci_cleanup; - FT_pci_scan_bus pci_scan_bus; - FT_pci_fill_info pci_fill_info; - FT_pci_lookup_name pci_lookup_name; -}; - // This checks if a system supports PCI bus. // We check the existence of /sys/bus/pci or /sys/bug/pci_express. bool IsPciSupported() { @@ -64,68 +37,6 @@ bool IsPciSupported() { file_util::PathExists(pcie_path)); } -// This dynamically opens libpci and get function pointers we need. Return -// NULL if library fails to open or any functions can not be located. -// Returned interface (if not NULL) should be deleted in FinalizeLibPci. -PciInterface* InitializeLibPci(const char* lib_name) { - scoped_ptr<PciInterface> interface(new PciInterface); -#if defined(DLOPEN_LIBPCI) - void* handle = dlopen(lib_name, RTLD_LAZY); - if (handle == NULL) { - VLOG(1) << "Failed to dlopen " << lib_name; - return NULL; - } - interface->lib_handle = handle; - interface->pci_alloc = reinterpret_cast<FT_pci_alloc>( - dlsym(handle, "pci_alloc")); - interface->pci_init = reinterpret_cast<FT_pci_init>( - dlsym(handle, "pci_init")); - interface->pci_cleanup = reinterpret_cast<FT_pci_cleanup>( - dlsym(handle, "pci_cleanup")); - interface->pci_scan_bus = reinterpret_cast<FT_pci_scan_bus>( - dlsym(handle, "pci_scan_bus")); - interface->pci_fill_info = reinterpret_cast<FT_pci_fill_info>( - dlsym(handle, "pci_fill_info")); - interface->pci_lookup_name = reinterpret_cast<FT_pci_lookup_name>( - dlsym(handle, "pci_lookup_name")); - if (interface->pci_alloc == NULL || - interface->pci_init == NULL || - interface->pci_cleanup == NULL || - interface->pci_scan_bus == NULL || - interface->pci_fill_info == NULL || - interface->pci_lookup_name == NULL) { - VLOG(1) << "Missing required function(s) from " << lib_name; - dlclose(handle); - return NULL; - } -#else // !defined(DLOPEN_LIBPCI) - interface->lib_handle = NULL; - interface->pci_alloc = reinterpret_cast<FT_pci_alloc>( - &pci_alloc); - interface->pci_init = reinterpret_cast<FT_pci_init>( - &pci_init); - interface->pci_cleanup = reinterpret_cast<FT_pci_cleanup>( - &pci_cleanup); - interface->pci_scan_bus = reinterpret_cast<FT_pci_scan_bus>( - &pci_scan_bus); - interface->pci_fill_info = reinterpret_cast<FT_pci_fill_info>( - &pci_fill_info); - interface->pci_lookup_name = reinterpret_cast<FT_pci_lookup_name>( - &pci_lookup_name); -#endif // !defined(DLOPEN_LIBPCI) - return interface.release(); -} - -// This close the dynamically opened libpci and delete the interface. -void FinalizeLibPci(PciInterface** interface) { -#if defined(DLOPEN_LIBPCI) - DCHECK(interface && *interface && (*interface)->lib_handle); - dlclose((*interface)->lib_handle); -#endif // defined(DLOPEN_LIBPCI) - delete (*interface); - *interface = NULL; -} - // Scan /etc/ati/amdpcsdb.default for "ReleaseVersion". // Return empty string on failing. std::string CollectDriverVersionATI() { @@ -263,22 +174,22 @@ bool CollectVideoCardInfo(content::GPUInfo* gpu_info) { } // TODO(zmo): be more flexible about library name. - PciInterface* interface = InitializeLibPci("libpci.so.3"); - if (interface == NULL) - interface = InitializeLibPci("libpci.so"); - if (interface == NULL) { + LibPciLoader libpci_loader; + if (!libpci_loader.Load("libpci.so.3") && + !libpci_loader.Load("libpci.so")) { VLOG(1) << "Failed to locate libpci"; return false; } - pci_access* access = (interface->pci_alloc)(); + pci_access* access = (libpci_loader.pci_alloc)(); DCHECK(access != NULL); - (interface->pci_init)(access); - (interface->pci_scan_bus)(access); + (libpci_loader.pci_init)(access); + (libpci_loader.pci_scan_bus)(access); bool primary_gpu_identified = false; for (pci_dev* device = access->devices; device != NULL; device = device->next) { - (interface->pci_fill_info)(device, 33); // Fill the IDs and class fields. + // Fill the IDs and class fields. + (libpci_loader.pci_fill_info)(device, 33); // TODO(zmo): there might be other classes that qualify as display devices. if (device->device_class != 0x0300) // Device class is DISPLAY_VGA. continue; @@ -292,19 +203,19 @@ bool CollectVideoCardInfo(content::GPUInfo* gpu_info) { // The current implementation of pci_lookup_name returns the same pointer // as the passed in upon success, and a different one (NULL or a pointer // to an error message) upon failure. - if ((interface->pci_lookup_name)(access, - buffer.get(), - buffer_size, - 1, - device->vendor_id) == buffer.get()) { + if ((libpci_loader.pci_lookup_name)(access, + buffer.get(), + buffer_size, + 1, + device->vendor_id) == buffer.get()) { gpu.vendor_string = buffer.get(); } - if ((interface->pci_lookup_name)(access, - buffer.get(), - buffer_size, - 2, - device->vendor_id, - device->device_id) == buffer.get()) { + if ((libpci_loader.pci_lookup_name)(access, + buffer.get(), + buffer_size, + 2, + device->vendor_id, + device->device_id) == buffer.get()) { std::string device_string = buffer.get(); size_t begin = device_string.find_first_of('['); size_t end = device_string.find_last_of(']'); @@ -341,8 +252,7 @@ bool CollectVideoCardInfo(content::GPUInfo* gpu_info) { gpu_info->amd_switchable = true; } - (interface->pci_cleanup)(access); - FinalizeLibPci(&interface); + (libpci_loader.pci_cleanup)(access); return (primary_gpu_identified); } |