summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2009-03-04 15:55:11 +1000
committerDave Airlie <airlied@redhat.com>2009-05-01 09:58:12 +1000
commitb2838fb61c3542f107014b285cbda097acae1e12 (patch)
treea23db52f69c6dac7e3d4863919ed30d51191d1cc
parentf14c6cd626273bd2f8b102ff661d11926619a99b (diff)
pciaccess: provide a method to detect if a device is boot VGA
When the linux kernel exposes this information, we can use this interface in the X server to detect whether the kernel believes the device we are looking at is the boot VGA device. Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--include/pciaccess.h2
-rw-r--r--src/common_interface.c14
-rw-r--r--src/linux_sysfs.c31
-rw-r--r--src/pciaccess_private.h1
4 files changed, 48 insertions, 0 deletions
diff --git a/include/pciaccess.h b/include/pciaccess.h
index cf32876..6413ae0 100644
--- a/include/pciaccess.h
+++ b/include/pciaccess.h
@@ -50,6 +50,8 @@ struct pci_slot_match;
extern "C" {
#endif
+int pci_device_is_boot_vga(struct pci_device *dev);
+
int pci_device_read_rom(struct pci_device *dev, void *buffer);
int __deprecated pci_device_map_region(struct pci_device *dev,
diff --git a/src/common_interface.c b/src/common_interface.c
index 8808fdf..5dcc707 100644
--- a/src/common_interface.c
+++ b/src/common_interface.c
@@ -108,6 +108,20 @@ pci_device_read_rom( struct pci_device * dev, void * buffer )
return (pci_sys->methods->read_rom)( dev, buffer );
}
+/**
+ * Probe a PCI (VGA) device to determine if its the boot VGA device
+ *
+ * \param dev Device whose VGA status to query
+ * \return
+ * Zero if not the boot VGA, 1 if the boot VGA.
+ */
+int
+pci_device_is_boot_vga( struct pci_device * dev )
+{
+ if (!pci_sys->methods->boot_vga)
+ return 0;
+ return pci_sys->methods->boot_vga( dev );
+}
/**
* Probe a PCI device to learn information about the device.
diff --git a/src/linux_sysfs.c b/src/linux_sysfs.c
index 8c3cf67..5afa7d2 100644
--- a/src/linux_sysfs.c
+++ b/src/linux_sysfs.c
@@ -75,6 +75,8 @@ static int pci_device_linux_sysfs_write( struct pci_device * dev,
const void * data, pciaddr_t offset, pciaddr_t size,
pciaddr_t * bytes_written );
+static int pci_device_linux_sysfs_boot_vga( struct pci_device * dev );
+
static const struct pci_system_methods linux_sysfs_methods = {
.destroy = NULL,
.destroy_device = NULL,
@@ -88,6 +90,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,
};
#define SYS_BUS_PCI "/sys/bus/pci/devices"
@@ -698,3 +701,31 @@ static void pci_device_linux_sysfs_enable(struct pci_device *dev)
write( fd, "1", 1 );
close(fd);
}
+
+static int pci_device_linux_sysfs_boot_vga(struct pci_device *dev)
+{
+ char name[256];
+ char reply[3];
+ int fd, bytes_read;
+ int ret = 0;
+
+ snprintf( name, 255, "%s/%04x:%02x:%02x.%1u/boot_vga",
+ SYS_BUS_PCI,
+ dev->domain,
+ dev->bus,
+ dev->dev,
+ dev->func );
+
+ fd = open( name, O_RDWR );
+ if (fd == -1)
+ return 0;
+
+ bytes_read = read(fd, reply, 1);
+ if (bytes_read != 1)
+ goto out;
+ if (reply[0] == '1')
+ ret = 1;
+out:
+ close(fd);
+ return ret;
+}
diff --git a/src/pciaccess_private.h b/src/pciaccess_private.h
index bff6903..769e181 100644
--- a/src/pciaccess_private.h
+++ b/src/pciaccess_private.h
@@ -60,6 +60,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 );
};
struct pci_device_mapping {