349.12

parent 779cda9a
/*
* Copyright (C) 2010-2012 NVIDIA Corporation
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
* 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:
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses>.
* 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.
*/
......@@ -60,40 +66,45 @@ void *nvalloc(size_t size)
/*
* nvstrcat() - allocate a new string, copying all given strings
* into it. taken from glib
* into it.
*/
char *nvstrcat(const char *str, ...)
{
unsigned int l;
va_list args;
char *s;
char *concat;
l = 1 + strlen(str);
va_start(args, str);
s = va_arg(args, char *);
while (s) {
l += strlen(s);
s = va_arg(args, char *);
const char *s;
char *result;
size_t len;
va_list ap;
/* walk the varargs to compute the length of the result string */
va_start(ap, str);
for (s = str, len = 1; s; s = va_arg(ap, char *)) {
len += strlen(s);
}
va_end(ap);
/* allocate the result string */
result = nvalloc(len);
if (!result) {
return result;
}
va_end(args);
result[0] = '\0';
concat = nvalloc(l);
concat[0] = 0;
/* concatenate the input strings, writing into the result string */
strcat(concat, str);
va_start(args, str);
s = va_arg(args, char *);
while (s) {
strcat(concat, s);
s = va_arg(args, char *);
va_start(ap, str);
for (s = str; s; s = va_arg(ap, char *)) {
strcat(result, s);
}
va_end(args);
return concat;
va_end(ap);
return result;
} /* nvstrcat() */
......
/*
* Copyright (C) 2010-2012 NVIDIA Corporation
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
* 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:
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses>.
* 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 __COMMON_UTILS_H__
......
/*
* Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
* 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:
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* 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 <stdio.h>
......
/*
* Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
* 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:
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* 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.
*/
#if !defined(__GEN_MANPAGE_OPTS_HELPER_H__)
......
/*
* Copyright (C) 2004 NVIDIA Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
* 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:
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses>.
* 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 <stdio.h>
......
/*
* Copyright (C) 2004 NVIDIA Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
* 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:
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses>.
* 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 __MSG_H__
......
/*
* Copyright (C) 2004-2010 NVIDIA Corporation
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
* 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:
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses>.
* 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.
*
*
* nvgetopt.c - portable getopt_long() replacement; removes the need
......
/*
* Copyright (C) 2004-2010 NVIDIA Corporation
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses>.
*
*
* nvgetopt.h
* 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 __NVGETOPT_H__
......
......@@ -38,6 +38,7 @@
#include <sys/wait.h>
#include "nvidia-modprobe-utils.h"
#include "pci-enum.h"
#define NV_PROC_MODPROBE_PATH "/proc/sys/kernel/modprobe"
#define NV_PROC_MODULES_PATH "/proc/modules"
......@@ -227,6 +228,20 @@ static int modprobe_helper(const int print_errors, const char *module_name)
const char *envp[] = { "PATH=/sbin", NULL };
FILE *fp;
/*
* Use PCI_BASE_CLASS_MASK to cover both types of DISPLAY controllers that
* NVIDIA ships (VGA = 0x300 and 3D = 0x302).
*/
struct pci_id_match id_match = {
NV_PCI_VENDOR_ID, /* Vendor ID = 0x10DE */
PCI_MATCH_ANY, /* Device ID = any */
PCI_MATCH_ANY, /* Subvendor ID = any */
PCI_MATCH_ANY, /* Subdevice ID = any */
0x0300, /* Device Class = PCI_BASE_CLASS_DISPLAY */
PCI_BASE_CLASS_MASK, /* Display Mask = base class only */
0 /* Initial number of matches */
};
modprobe_path[0] = '\0';
if (module_name == NULL || module_name[0] == '\0') {
......@@ -240,6 +255,27 @@ static int modprobe_helper(const int print_errors, const char *module_name)
return 1;
}
/*
* Before attempting to load the module, look for any NVIDIA PCI devices.
* If none exist, exit instead of attempting the modprobe, because doing so
* would issue error messages that are really irrelevant if there are no
* NVIDIA PCI devices present.
*
* If our check fails, for whatever reason, continue with the modprobe just
* in case.
*/
status = pci_enum_match_id(&id_match);
if (status == 0 && id_match.num_matches == 0)
{
if (print_errors)
{
fprintf(stderr,
"NVIDIA: no NVIDIA devices found\n");
}
return 0;
}
/* Only attempt to load the kernel module if root. */
if (geteuid() != 0)
......
......@@ -51,6 +51,8 @@
((x <= NV_FRONTEND_CONTROL_DEVICE_MINOR_MAX) && \
(x > NV_FRONTEND_CONTROL_DEVICE_MINOR_MIN))
#define NV_PCI_VENDOR_ID 0x10DE
#if defined(NV_LINUX)
int nvidia_modprobe(const int print_errors, int module_instance);
......
MODPROBE_UTILS_SRC += nvidia-modprobe-utils.c
MODPROBE_UTILS_SRC += pci-sysfs.c
MODPROBE_UTILS_EXTRA_DIST += nvidia-modprobe-utils.h
MODPROBE_UTILS_EXTRA_DIST += nvidia-modprobe-utils.mk
MODPROBE_UTILS_EXTRA_DIST += pci-enum.h
/*
* (C) Copyright IBM Corporation 2006
*
* Copyright (c) 2007 Paulo R. Zanoni, Tiago Vignatti
*
* Copyright 2009 Red Hat, Inc.
*
* Copyright (c) 2014 NVIDIA Corporation
*
* All Rights Reserved.
*
* 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.
*/
/**
* pci-enum.h
*
* Based on libpciaccess/include/pciaccess.h from libpciaccess-0.12.1, which
* can be found here:
*
* http://cgit.freedesktop.org/xorg/lib/libpciaccess
*
* Original authors: Ian Romanick <idr@us.ibm.com>, Paulo R. Zanoni,
* Tiago Vignatti
*/
#ifndef PCI_ENUM_H
#define PCI_ENUM_H
#include <inttypes.h>
struct pci_id_match;
#ifdef __cplusplus
extern "C" {
#endif
int pci_enum_match_id(struct pci_id_match *);
#ifdef __cplusplus
}
#endif
#define PCI_MATCH_ANY (~0U)
#define PCI_BASE_CLASS_MASK 0xff00
#define PCI_SUB_CLASS_MASK 0x00ff
#define PCI_FULL_CLASS_MASK PCI_BASE_CLASS_MASK | PCI_SUB_CLASS_MASK
/**
* Compare two PCI ID values (either vendor or device). This is used
* internally to compare the fields of pci_id_match to the fields of
* pci_device.
*/
#define PCI_ID_COMPARE(a, b) \
(((a) == PCI_MATCH_ANY) || ((a) == (b)))
/**
*/
struct pci_id_match {
/**
* Device/vendor matching controls
*
* Control the search based on the device, vendor, subdevice, or subvendor
* IDs. Setting any of these fields to PCI_MATCH_ANY will cause the field
* to not be used in the comparison.
*/
/*@{*/
uint32_t vendor_id;
uint32_t device_id;
uint32_t subvendor_id;
uint32_t subdevice_id;
/*@}*/
/**
* Device class matching controls
*
* Device's class and subclass. The class is at bits [15:8], subclass is at
* bits [7:0].
*/
/*@{*/
uint16_t device_class;
uint16_t device_class_mask;
/*@}*/
/**
* Match results
*
* Specifies the number of devices found that match this criteria.
*/
/*@{*/
uint16_t num_matches;
};
#endif /* PCI_ENUM_H */
/*
* (C) Copyright IBM Corporation 2006
*
* Copyright (c) 2014 NVIDIA Corporation
*
* All Rights Reserved.
*
* 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.
*/
/**
* pcienum-sysfs.c
*
* Based on libpciaccess/src/linux_sysfs.c from libpciaccess-0.12.1, which was
* found here:
*
* http://cgit.freedesktop.org/xorg/lib/libpciaccess
*
* Access PCI subsystem using Linux's sysfs interface. This interface is
* available starting somewhere in the late 2.5.x kernel phase, and is the
* preferred method on all 2.6.x kernels.
*
* Original author: Ian Romanick <idr@us.ibm.com>
*/
#if defined(NV_LINUX)
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <dirent.h>
#include <errno.h>
#include "pci-enum.h"
#define SYS_BUS_PCI "/sys/bus/pci/devices"
static int pci_sysfs_read_cfg(uint16_t, uint16_t, uint16_t, uint16_t, void *,
uint16_t size, uint16_t *);
static int find_matches(struct pci_id_match *match);
/**
* Attempt to access PCI subsystem using Linux's sysfs interface to enumerate
* the matched devices.
*/
int
pci_enum_match_id(struct pci_id_match *match)
{
int err = 0;
struct stat st;
/*
* If the directory "/sys/bus/pci/devices" exists, then the PCI subsystem
* can be accessed using this interface.
*/
match->num_matches = 0;
if (stat(SYS_BUS_PCI, &st) == 0)
{
err = find_matches(match);
}
else
{
err = errno;
}
return err;
}
/**
* The sysfs lookup method uses the directory entries in /sys/bus/pci/devices
* to enumerate all PCI devices, and then uses a file in each that is mapped to
* the device's PCI config space to extract the data to match against.
*/
static int
find_matches(struct pci_id_match *match)
{
struct dirent *d;
DIR *sysfs_pci_dir;
int err = 0;
sysfs_pci_dir = opendir(SYS_BUS_PCI);
if (sysfs_pci_dir == NULL)
{
return errno;
}
while ((d = readdir(sysfs_pci_dir)) != NULL)
{
uint8_t config[48];
uint16_t bytes;
unsigned dom, bus, dev, func;
uint16_t vendor_id, device_id, subvendor_id, subdevice_id;
uint16_t device_class;
/* Ignore the . and .. dirents */
if ((strcmp(d->d_name, ".") == 0) || (strcmp(d->d_name, "..") == 0))
{
continue;
}
sscanf(d->d_name, "%04x:%02x:%02x.%1u",
& dom, & bus, & dev, & func);
err = pci_sysfs_read_cfg(dom, bus, dev, func, config, 48, & bytes);
if ((bytes == 48) && !err)
{
vendor_id = (uint16_t)config[0] + ((uint16_t)config[1] << 8);
device_id = (uint16_t)config[2] + ((uint16_t)config[3] << 8);
device_class = (uint16_t)config[10] +
((uint16_t)config[11] << 8);
subvendor_id = (uint16_t)config[44] +
((uint16_t)config[45] << 8);
subdevice_id = (uint16_t)config[46] +
((uint16_t)config[47] << 8);
/*
* This logic, originally in common_iterator.c, will tell if
* this device is a match for the search criteria.
*/
if (PCI_ID_COMPARE(match->vendor_id, vendor_id) &&
PCI_ID_COMPARE(match->device_id, device_id) &&
PCI_ID_COMPARE(match->subvendor_id, subvendor_id) &&
PCI_ID_COMPARE(match->subdevice_id, subdevice_id) &&
((device_class & match->device_class_mask) ==
match->device_class))
{
match->num_matches++;
}
}
if (err)
{
break;
}
}
closedir(sysfs_pci_dir);
return err;
}
static int
pci_sysfs_read_cfg(uint16_t domain, uint16_t bus, uint16_t device,
uint16_t function, void * data, uint16_t size,
uint16_t *bytes_read)
{
char name[256];
uint16_t temp_size = size;
int err = 0;
int fd;
char *data_bytes = data;
if (bytes_read != NULL)
{
*bytes_read = 0;
}
/*
* Each device has a directory under sysfs. Within that directory there
* is a file named "config". This file used to access the PCI config
* space. It is used here to obtain most of the information about the
* device.
*/
snprintf(name, 255, "%s/%04x:%02x:%02x.%1u/config",
SYS_BUS_PCI, domain, bus, device, function);
fd = open(name, O_RDONLY);
if (fd < 0)
{
return errno;
}
while (temp_size > 0)
{
const ssize_t bytes = read(fd, data_bytes, temp_size);
/*
* If zero bytes were read, then we assume it's the end of the
* config file.
*/
if (bytes <= 0)
{
err = errno;
break;
}
temp_size -= bytes;
data_bytes += bytes;
}
if (bytes_read != NULL)
{
*bytes_read = size - temp_size;
}
close(fd);
return err;
}
#endif /* defined(NV_LINUX) */
#
# Copyright (C) 2008 NVIDIA Corporation
#
# This program is free software; you can redistribute it and/or modify it