summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Plattner <aplattner@nvidia.com>2022-01-11 10:01:22 -0800
committerAaron Plattner <aplattner@nvidia.com>2022-01-11 10:01:22 -0800
commitaa1ba6f9761943412b2936007fc1e0b99ebbdc2d (patch)
treeb3f879c765e130380696500e1ff461d6e93a462b
parentd2663213a9fdf484584b8648d3d1ccc4d45a4134 (diff)
510.39.01510.39.01main
-rw-r--r--Makefile10
-rw-r--r--common-utils/msg.c2
-rw-r--r--common-utils/nvgetopt.c2
-rw-r--r--common-utils/nvpci-utils.c65
-rw-r--r--common-utils/nvpci-utils.h33
-rw-r--r--common-utils/src.mk13
-rw-r--r--extract_edids.c6
-rw-r--r--make_usable.c52
-rw-r--r--multiple_screens.c6
-rw-r--r--nvidia-xconfig.c2
-rw-r--r--nvidia-xconfig.h1
-rw-r--r--query_gpu_info.c11
-rw-r--r--util.c31
-rw-r--r--utils.mk3
-rw-r--r--version.mk2
15 files changed, 201 insertions, 38 deletions
diff --git a/Makefile b/Makefile
index 1a5c70c..87853b2 100644
--- a/Makefile
+++ b/Makefile
@@ -25,6 +25,7 @@
# include common variables and functions
##############################################################################
+COMMON_UTILS_PCIACCESS = 1
include utils.mk
@@ -87,14 +88,14 @@ common_cflags += -DPROGRAM_NAME=\"nvidia-xconfig\"
CFLAGS += $(common_cflags)
HOST_CFLAGS += $(common_cflags)
-LIBS += -lm
+LIBS += -lm -lpciaccess
ifneq ($(TARGET_OS),FreeBSD)
LIBS += -ldl
endif
ifeq ($(TARGET_OS),SunOS)
- LIBS += -lscf
+ LIBS += -lscf -ldevinfo
endif
@@ -119,7 +120,10 @@ MANPAGE_install: $(MANPAGE)
$(eval $(call DEBUG_INFO_RULES, $(NVIDIA_XCONFIG)))
$(NVIDIA_XCONFIG).unstripped: $(OBJS)
$(call quiet_cmd,LINK) $(CFLAGS) $(LDFLAGS) $(BIN_LDFLAGS) \
- -o $@ $(OBJS) $(LIBS)
+ $(PCIACCESS_LDFLAGS) -o $@ $(OBJS) $(LIBS)
+
+# make_usable.c includes pciaccess.h
+$(call BUILD_OBJECT_LIST,make_usable.c): CFLAGS += $(PCIACCESS_CFLAGS)
# define the rule to build each object file
$(foreach src, $(SRC), $(eval $(call DEFINE_OBJECT_RULE,TARGET,$(src))))
diff --git a/common-utils/msg.c b/common-utils/msg.c
index 8a78530..70772a2 100644
--- a/common-utils/msg.c
+++ b/common-utils/msg.c
@@ -113,7 +113,7 @@ do { \
NV_VSNPRINTF(buf, fmt); \
format(stream, prefix, buf, whitespace); \
free (buf); \
-} while(0)
+} while (0)
/*
diff --git a/common-utils/nvgetopt.c b/common-utils/nvgetopt.c
index 286aee8..5ae3a14 100644
--- a/common-utils/nvgetopt.c
+++ b/common-utils/nvgetopt.c
@@ -189,7 +189,7 @@ int nvgetopt(int argc,
if (a[0] == '-') a++;
if (a[0] == '+') a++;
- while(a[0]) { a[0] = a[1]; a++; }
+ while (a[0]) { a[0] = a[1]; a++; }
/*
* decrement argv_index so that we process this
diff --git a/common-utils/nvpci-utils.c b/common-utils/nvpci-utils.c
new file mode 100644
index 0000000..62946d2
--- /dev/null
+++ b/common-utils/nvpci-utils.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2021 NVIDIA Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "nvpci-utils.h"
+
+/*
+ * libpciaccess stores the device class in bits 16-23, subclass in 8-15, and
+ * interface in bits 0-7 of dev->device_class. We care only about the class
+ * and subclass.
+ */
+const uint32_t PCI_CLASS_DISPLAY_VGA = 0x30000;
+const uint32_t PCI_CLASS_SUBCLASS_MASK = 0xffff00;
+
+/*
+ * nvpci_find_gpu_by_vendor() - use libpciaccess to find all VGA and 3D PCI
+ * devices matching the passed-in vendor_id (which may be set to PCI_MATCH_ANY).
+ * The caller is responsible for calling pci_system_init() before using this
+ * function, and pci_system_cleanup() when libpciaccess is no longer needed.
+ */
+struct pci_device_iterator *nvpci_find_gpu_by_vendor(uint32_t vendor_id)
+{
+ const struct pci_id_match match = {
+ .vendor_id = vendor_id,
+ .device_id = PCI_MATCH_ANY,
+ .subvendor_id = PCI_MATCH_ANY,
+ .subdevice_id = PCI_MATCH_ANY,
+ .device_class = PCI_CLASS_DISPLAY_VGA,
+ /*
+ * Ignore bit 1 of the subclass, to allow both 0x30000 (VGA controller)
+ * and 0x30200 (3D controller).
+ */
+ .device_class_mask = PCI_CLASS_SUBCLASS_MASK & ~0x200,
+ };
+
+ return pci_id_match_iterator_create(&match);
+}
+
+/*
+ * nvpci_dev_is_vga() - test whether the passed-in struct pci_device* has the
+ * VGA device class 0x0300 (and not 3D class 0x0302).
+ */
+int nvpci_dev_is_vga(struct pci_device *dev)
+{
+ return (dev->device_class & PCI_CLASS_SUBCLASS_MASK) ==
+ PCI_CLASS_DISPLAY_VGA;
+}
diff --git a/common-utils/nvpci-utils.h b/common-utils/nvpci-utils.h
new file mode 100644
index 0000000..9813e90
--- /dev/null
+++ b/common-utils/nvpci-utils.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2021 NVIDIA Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __NVPCI_UTILS_H__
+#define __NVPCI_UTILS_H__
+
+#include <pciaccess.h>
+
+#define NV_PCI_VENDOR_ID 0x10de
+
+struct pci_device_iterator *nvpci_find_gpu_by_vendor(uint32_t vendor_id);
+int nvpci_dev_is_vga(struct pci_device *dev);
+
+#endif /* __NVPCI_UTILS_H__ */
diff --git a/common-utils/src.mk b/common-utils/src.mk
index 6dbed7a..bb1e1d3 100644
--- a/common-utils/src.mk
+++ b/common-utils/src.mk
@@ -1,5 +1,8 @@
# makefile fragment included by nvidia-xconfig, nvidia-settings, and nvidia-installer
+# the including makefile should set this if the relevant program uses pciaccess
+COMMON_UTILS_PCIACCESS ?=
+
COMMON_UTILS_SRC += nvgetopt.c
COMMON_UTILS_SRC += common-utils.c
COMMON_UTILS_SRC += msg.c
@@ -9,6 +12,16 @@ COMMON_UTILS_EXTRA_DIST += common-utils.h
COMMON_UTILS_EXTRA_DIST += msg.h
COMMON_UTILS_EXTRA_DIST += src.mk
+# only build nvpci-utils.c for programs that actually use libpciaccess, to
+# prevent other programs from needing to set the right CFLAGS/LDFLAGS for code
+# they won't use. Otherwise, just package it in the source tarball.
+ifneq ($(COMMON_UTILS_PCIACCESS),)
+ COMMON_UTILS_SRC += nvpci-utils.c
+else
+ COMMON_UTILS_EXTRA_DIST += nvpci-utils.c
+endif
+COMMON_UTILS_EXTRA_DIST += nvpci-utils.h
+
# gen-manpage-opts-helper.c is listed in EXTRA_DIST, rather than SRC,
# because it is not compiled into the utilities themselves, but used
# when building the utility's gen-manpage-opts
diff --git a/extract_edids.c b/extract_edids.c
index 8e2d10e..0dac31a 100644
--- a/extract_edids.c
+++ b/extract_edids.c
@@ -249,7 +249,7 @@ int extract_edids(Options *op)
/* scan through the whole file, and build a list of pEdids */
- while(1) {
+ while (1) {
if (fileType == LOG_FILE) {
@@ -485,7 +485,7 @@ static int readEdidDataforLogFile(FilePtr pFile, EdidPtr pEdid)
state = STATE_LOOKING_FOR_TOP_NIBBLE;
k = 0;
- while(1) {
+ while (1) {
c = pFile->current[0];
@@ -673,7 +673,7 @@ static int readEdidDataforTextFile(FilePtr pFile, EdidPtr pEdid)
state = STATE_LOOKING_FOR_TOP_NIBBLE;
k = 0;
- while(1) {
+ while (1) {
c = pFile->current[0];
diff --git a/make_usable.c b/make_usable.c
index 34fadd5..27bd307 100644
--- a/make_usable.c
+++ b/make_usable.c
@@ -29,6 +29,7 @@
#include "xf86Parser.h"
#include "configProcs.h"
#include "msg.h"
+#include "nvpci-utils.h"
static void ensure_module_loaded(XConfigPtr config, char *name);
@@ -238,6 +239,32 @@ int update_server_flags(Options *op, XConfigPtr config)
+static int count_non_nv_gpus(void)
+{
+ struct pci_device_iterator *iter;
+ struct pci_device *dev;
+ int count = 0;
+
+ if (pci_system_init()) {
+ return -1;
+ }
+
+ iter = nvpci_find_gpu_by_vendor(PCI_MATCH_ANY);
+
+ for (dev = pci_device_next(iter); dev; dev = pci_device_next(iter)) {
+ if (dev->vendor_id != NV_PCI_VENDOR_ID) {
+ count++;
+ }
+ }
+
+ pci_system_cleanup();
+
+ return count;
+}
+
+
+
+
/*
* update_device() - update the device; there is a lot of information
* in the device that is not relevant to the NVIDIA X driver. In
@@ -254,7 +281,6 @@ static int update_device(Options *op, XConfigPtr config, XConfigDevicePtr device
size_t index_id;
XConfigDevicePtr next;
XConfigOptionPtr options;
- DevicesPtr pDevices;
next = device->next;
options = device->options;
@@ -285,25 +311,15 @@ static int update_device(Options *op, XConfigPtr config, XConfigDevicePtr device
* 3. If we want to write busid with option --busid
* 4. If we want to preserve existing bus id
* 5. If there are multiple screens
+ * 6. If the system has any non-NVIDIA GPUs
*/
if (GET_BOOL_OPTION(op->boolean_option_values, ENABLE_PRIME_OPTION) &&
op->busid == NULL) {
- pDevices = find_devices(op);
- if (!pDevices || pDevices->nDevices < 1) {
- nv_error_msg("Unable to find any GPUs in the system.");
- return FALSE;
- }
- if (device->index_id >= pDevices->nDevices) {
- nv_error_msg("Invalid GPU index value.");
+ device->busid = nv_format_busid(op, device->index_id);
+ if (device->busid == NULL) {
return FALSE;
- }
- device->busid = nvalloc(32);
-
- xconfigFormatPciBusString(device->busid, 32,
- pDevices->devices[device->index_id].dev.domain,
- pDevices->devices[device->index_id].dev.bus,
- pDevices->devices[device->index_id].dev.slot, 0);
+ }
} else if (op->busid == NV_DISABLE_STRING_OPTION) {
device->busid = NULL;
} else if (op->busid) {
@@ -317,7 +333,13 @@ static int update_device(Options *op, XConfigPtr config, XConfigDevicePtr device
device->busid = NULL;
}
} else if (config->screens->next) {
+ /* enable_separate_x_screens() already generated a busid string */
device->busid = busid;
+ } else if (count_non_nv_gpus() > 0) {
+ device->busid = nv_format_busid(op, device->index_id);
+ if (device->busid == NULL) {
+ return FALSE;
+ }
}
device->chipid = -1;
diff --git a/multiple_screens.c b/multiple_screens.c
index bfa9b23..6f0fded 100644
--- a/multiple_screens.c
+++ b/multiple_screens.c
@@ -638,11 +638,7 @@ static int enable_separate_x_screens(Options *op, XConfigPtr config,
continue;
}
- screenlist[i]->device->busid = nvalloc(32);
- xconfigFormatPciBusString(screenlist[i]->device->busid, 32,
- pDevices->devices[i].dev.domain,
- pDevices->devices[i].dev.bus,
- pDevices->devices[i].dev.slot, 0);
+ screenlist[i]->device->busid = nv_format_busid(op, i);
screenlist[i]->device->board = nvstrdup(pDevices->devices[i].name);
}
diff --git a/nvidia-xconfig.c b/nvidia-xconfig.c
index 3144771..40ca027 100644
--- a/nvidia-xconfig.c
+++ b/nvidia-xconfig.c
@@ -906,7 +906,7 @@ static int write_xconfig(Options *op, XConfigPtr config, int first_touch)
* to the default depth of the first screen
*/
if (op->disable_scf == FALSE) {
- if(!update_scf_depth(config->screens[0].defaultdepth)) {
+ if (!update_scf_depth(config->screens[0].defaultdepth)) {
goto done;
}
}
diff --git a/nvidia-xconfig.h b/nvidia-xconfig.h
index 2d345e6..be7d13c 100644
--- a/nvidia-xconfig.h
+++ b/nvidia-xconfig.h
@@ -200,6 +200,7 @@ typedef struct {
/* util.c */
int copy_file(const char *srcfile, const char *dstfile, mode_t mode);
+char *nv_format_busid(Options *op, int index);
/* make_usable.c */
diff --git a/query_gpu_info.c b/query_gpu_info.c
index 01e6152..2b753c6 100644
--- a/query_gpu_info.c
+++ b/query_gpu_info.c
@@ -27,8 +27,6 @@
static char *display_device_mask_to_display_device_name(unsigned int mask);
-#define BUS_ID_STRING_LENGTH 32
-
/*
* query_gpu_info() - query information about the GPU, and print it
@@ -40,7 +38,7 @@ int query_gpu_info(Options *op)
DevicesPtr pDevices;
DisplayDevicePtr pDisplayDevice;
int i, j;
- char *name, busid[BUS_ID_STRING_LENGTH];
+ char *name, *busid;
/* query the GPU information */
@@ -62,12 +60,9 @@ int query_gpu_info(Options *op)
nv_info_msg(TAB, "Name : %s", pDevices->devices[i].name);
nv_info_msg(TAB, "UUID : %s", pDevices->devices[i].uuid);
- memset(busid, 0, BUS_ID_STRING_LENGTH);
- xconfigFormatPciBusString(busid, BUS_ID_STRING_LENGTH,
- pDevices->devices[i].dev.domain,
- pDevices->devices[i].dev.bus,
- pDevices->devices[i].dev.slot, 0);
+ busid = nv_format_busid(op, i);
nv_info_msg(TAB, "PCI BusID : %s", busid);
+ nvfree(busid);
nv_info_msg(NULL, "");
nv_info_msg(TAB, "Number of Display Devices: %d",
diff --git a/util.c b/util.c
index cfc4a2d..1c56bba 100644
--- a/util.c
+++ b/util.c
@@ -171,3 +171,34 @@ void xconfigPrint(MsgType t, const char *msg)
if (newline) nv_info_msg_to_file(stream, NULL, "");
} /* xconfigPrint */
+
+/* a round number longer than "PCI:bus@domain:slot:function" */
+#define BUS_ID_STRING_LENGTH 32
+
+/*
+ * nv_format_busid() - returns a newly allocated formatted string with the PCI
+ * Bus ID of the device with the given index, or NULL on failure.
+ */
+char *nv_format_busid(Options *op, int index)
+{
+ char buf[BUS_ID_STRING_LENGTH];
+ DevicesPtr pDevices;
+ NvCfgPciDevice *dev;
+
+ pDevices = find_devices(op);
+ if (!pDevices || pDevices->nDevices < 1) {
+ nv_error_msg("Unable to find any GPUs in the system.");
+ return NULL;
+ }
+ if (index >= pDevices->nDevices) {
+ nv_error_msg("Invalid GPU index value.");
+ return NULL;
+ }
+
+ dev = &pDevices->devices[index].dev;
+
+ xconfigFormatPciBusString(buf, sizeof(buf),
+ dev->domain, dev->bus, dev->slot, 0);
+
+ return nvstrdup(buf);
+}
diff --git a/utils.mk b/utils.mk
index dd68d48..2b15880 100644
--- a/utils.mk
+++ b/utils.mk
@@ -186,6 +186,8 @@ NV_QUIET_COMMAND_REMOVED_TARGET_PREFIX ?=
NV_GENERATED_HEADERS ?=
+PCIACCESS_CFLAGS ?=
+PCIACCESS_LDFLAGS ?=
##############################################################################
# This makefile uses the $(eval) builtin function, which was added in
@@ -380,6 +382,7 @@ BUILD_OBJECT_LIST_WITH_DIR = \
BUILD_OBJECT_LIST = \
$(call BUILD_OBJECT_LIST_WITH_DIR,$(1),$(OUTPUTDIR))
+$(call BUILD_OBJECT_LIST,nvpci-utils.c): CFLAGS += $(PCIACCESS_CFLAGS)
##############################################################################
# function to generate a list of dependency files from their
diff --git a/version.mk b/version.mk
index 8e23d30..5e08b7b 100644
--- a/version.mk
+++ b/version.mk
@@ -1,4 +1,4 @@
-NVIDIA_VERSION = 495.46
+NVIDIA_VERSION = 510.39.01
# This file.
VERSION_MK_FILE := $(lastword $(MAKEFILE_LIST))