From 3c10274498054ffe10a8d5fab2cf101bbe463e03 Mon Sep 17 00:00:00 2001 From: Tiago Vignatti Date: Sat, 22 May 2010 19:21:45 +0300 Subject: [PATCH 3/3] vgaarb: HACK: assume safe state if only one card decodes If only one card is decoding, then no conflicts exist and we let everyone routes VGA. A hook was also introduced there to restart the arbiter to its initial state when any userspace app releases. Signed-off-by: Tiago Vignatti --- drivers/gpu/vga/vgaarb.c | 30 ++++++++++++++++++++++++++++-- 1 files changed, 28 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c index b87569e..7740c20 100644 --- a/drivers/gpu/vga/vgaarb.c +++ b/drivers/gpu/vga/vgaarb.c @@ -570,7 +570,7 @@ static inline void vga_update_device_decodes(struct vga_device *vgadev, vga_iostate_to_str(vgadev->decodes), vga_iostate_to_str(vgadev->owns)); - +#if 0 /* if we own the decodes we should move them along to another card */ if ((vgadev->owns & old_decodes) && (vga_count > 1)) { @@ -587,7 +587,7 @@ static inline void vga_update_device_decodes(struct vga_device *vgadev, } } } - +#endif /* change decodes counter */ if (old_decodes != new_decodes) { if (new_decodes & (VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM)) @@ -596,6 +596,17 @@ static inline void vga_update_device_decodes(struct vga_device *vgadev, vga_decode_count--; } pr_debug("vgaarb: decoding count now is: %d\n", vga_decode_count); + + /* if only one card is decoding, then no conflicts exist and we let + * everyone routes VGA */ + if (vga_decode_count < 2) + list_for_each_entry(new_vgadev, &vga_list, list) { + pr_info("vgaarb: setting owner to PCI:%s\n", + pci_name(new_vgadev->pdev)); + conflict = __vga_tryget(new_vgadev, VGA_RSRC_LEGACY_MASK); + if (!conflict) + __vga_put(new_vgadev, VGA_RSRC_LEGACY_MASK); + } } void __vga_set_legacy_decoding(struct pci_dev *pdev, unsigned int decodes, bool userspace) @@ -1119,6 +1130,7 @@ static int vga_arb_release(struct inode *inode, struct file *file) { struct vga_arb_private *priv = file->private_data; struct vga_arb_user_card *uc; + struct pci_dev *pdev; unsigned long flags; int i; @@ -1144,6 +1156,20 @@ static int vga_arb_release(struct inode *inode, struct file *file) kfree(priv); + /* TODO: add some description justifying that only one userspace + * application should be using the arbiter. + * + * Right now, everytime one application releases, the arbiter is + * 'restarted' to the initial sate, i.e. not sane where all cards need to + * decode VGA legacy. + */ + pdev = NULL; + while ((pdev = + pci_get_subsys(PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_ANY_ID, pdev)) != NULL) { + vga_arbiter_del_pci_device(pdev); + vga_arbiter_add_pci_device(pdev); + } return 0; } -- 1.6.0.4