diff options
author | Dave Airlie <airlied@redhat.com> | 2009-07-16 15:36:30 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-07-16 15:36:30 +1000 |
commit | 5d1bdf0cb51c19efd6e2b2c0a463ace9443c48d9 (patch) | |
tree | f0f680c7a9f349cea7ff339cb260ac47b56ca24f | |
parent | 9ae22c87743c624bda593a1ef4bd4eca01c65655 (diff) |
add support for finding if something has a kernel driver
-rw-r--r-- | include/pciaccess.h | 2 | ||||
-rw-r--r-- | src/common_interface.c | 15 | ||||
-rw-r--r-- | src/linux_sysfs.c | 21 | ||||
-rw-r--r-- | src/pciaccess_private.h | 1 |
4 files changed, 39 insertions, 0 deletions
diff --git a/include/pciaccess.h b/include/pciaccess.h index 2230b27..13d92d7 100644 --- a/include/pciaccess.h +++ b/include/pciaccess.h @@ -75,6 +75,8 @@ struct pci_slot_match; extern "C" { #endif +int pci_device_has_kernel_driver(struct pci_device *dev); + int pci_device_is_boot_vga(struct pci_device *dev); int pci_device_read_rom(struct pci_device *dev, void *buffer); diff --git a/src/common_interface.c b/src/common_interface.c index 5dcc707..d46feab 100644 --- a/src/common_interface.c +++ b/src/common_interface.c @@ -124,6 +124,21 @@ pci_device_is_boot_vga( struct pci_device * dev ) } /** + * Probe a PCI device to determine if a kernel driver is attached. + * + * \param dev Device to query + * \return + * Zero if no driver attached, 1 if attached kernel drviver + */ +int +pci_device_has_kernel_driver( struct pci_device * dev ) +{ + if (!pci_sys->methods->has_kernel_driver) + return 0; + return pci_sys->methods->has_kernel_driver( dev ); +} + +/** * Probe a PCI device to learn information about the device. * * Probes a PCI device to learn various information about the device. Before diff --git a/src/linux_sysfs.c b/src/linux_sysfs.c index 1ae9e52..65e1cf6 100644 --- a/src/linux_sysfs.c +++ b/src/linux_sysfs.c @@ -76,6 +76,7 @@ static int pci_device_linux_sysfs_write( struct pci_device * dev, pciaddr_t * bytes_written ); static int pci_device_linux_sysfs_boot_vga( struct pci_device * dev ); +static int pci_device_linux_sysfs_has_kernel_driver(struct pci_device *dev); static const struct pci_system_methods linux_sysfs_methods = { .destroy = NULL, @@ -91,6 +92,7 @@ static const struct pci_system_methods linux_sysfs_methods = { .fill_capabilities = pci_fill_capabilities_generic, .enable = pci_device_linux_sysfs_enable, .boot_vga = pci_device_linux_sysfs_boot_vga, + .has_kernel_driver = pci_device_linux_sysfs_has_kernel_driver, }; #define SYS_BUS_PCI "/sys/bus/pci/devices" @@ -729,3 +731,22 @@ out: close(fd); return ret; } + +static int pci_device_linux_sysfs_has_kernel_driver(struct pci_device *dev) +{ + char name[256]; + struct stat dummy; + int ret; + + snprintf( name, 255, "%s/%04x:%02x:%02x.%1u/driver", + SYS_BUS_PCI, + dev->domain, + dev->bus, + dev->dev, + dev->func ); + + ret = stat(name, &dummy); + if (ret < 0) + return 0; + return 1; +} diff --git a/src/pciaccess_private.h b/src/pciaccess_private.h index 220673d..a45fa8f 100644 --- a/src/pciaccess_private.h +++ b/src/pciaccess_private.h @@ -61,6 +61,7 @@ struct pci_system_methods { int (*fill_capabilities)( struct pci_device * dev ); void (*enable)( struct pci_device *dev ); int (*boot_vga)( struct pci_device *dev ); + int (*has_kernel_driver)( struct pci_device *dev ); }; struct pci_device_mapping { |