add support for finding if something has a kernel driver
authorDave Airlie <airlied@redhat.com>
Thu, 16 Jul 2009 05:36:30 +0000 (15:36 +1000)
committerDave Airlie <airlied@redhat.com>
Thu, 16 Jul 2009 05:36:30 +0000 (15:36 +1000)
include/pciaccess.h
src/common_interface.c
src/linux_sysfs.c
src/pciaccess_private.h

index 2230b27..13d92d7 100644 (file)
@@ -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);
index 5dcc707..d46feab 100644 (file)
@@ -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
index 1ae9e52..65e1cf6 100644 (file)
@@ -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;
+}
index 220673d..a45fa8f 100644 (file)
@@ -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 {