^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * vgaarb.c: Implements the VGA arbitration. For details refer to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Documentation/gpu/vgaarbiter.rst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * (C) Copyright 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * (C) Copyright 2007 Paulo R. Zanoni <przanoni@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * (C) Copyright 2007, 2009 Tiago Vignatti <vignatti@freedesktop.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Permission is hereby granted, free of charge, to any person obtaining a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * copy of this software and associated documentation files (the "Software"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * to deal in the Software without restriction, including without limitation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * the rights to use, copy, modify, merge, publish, distribute, sublicense,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * and/or sell copies of the Software, and to permit persons to whom the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Software is furnished to do so, subject to the following conditions:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * The above copyright notice and this permission notice (including the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * paragraph) shall be included in all copies or substantial portions of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * Software.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * DEALINGS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * IN THE SOFTWARE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define pr_fmt(fmt) "vgaarb: " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define vgaarb_dbg(dev, fmt, arg...) dev_dbg(dev, "vgaarb: " fmt, ##arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define vgaarb_info(dev, fmt, arg...) dev_info(dev, "vgaarb: " fmt, ##arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define vgaarb_err(dev, fmt, arg...) dev_err(dev, "vgaarb: " fmt, ##arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <linux/poll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <linux/miscdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <linux/screen_info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <linux/vt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include <linux/console.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #include <linux/vgaarb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static void vga_arbiter_notify_clients(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * We keep a list of all vga devices in the system to speed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * up the various operations of the arbiter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct vga_device {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct pci_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) unsigned int decodes; /* what does it decodes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) unsigned int owns; /* what does it owns */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) unsigned int locks; /* what does it locks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) unsigned int io_lock_cnt; /* legacy IO lock count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) unsigned int mem_lock_cnt; /* legacy MEM lock count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) unsigned int io_norm_cnt; /* normal IO count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) unsigned int mem_norm_cnt; /* normal MEM count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) bool bridge_has_one_vga;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /* allow IRQ enable/disable hook */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) void *cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) void (*irq_set_state)(void *cookie, bool enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) unsigned int (*set_vga_decode)(void *cookie, bool decode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static LIST_HEAD(vga_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static int vga_count, vga_decode_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static bool vga_arbiter_used;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static DEFINE_SPINLOCK(vga_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static DECLARE_WAIT_QUEUE_HEAD(vga_wait_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static const char *vga_iostate_to_str(unsigned int iostate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /* Ignore VGA_RSRC_IO and VGA_RSRC_MEM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) iostate &= VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) switch (iostate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) case VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return "io+mem";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) case VGA_RSRC_LEGACY_IO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return "io";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) case VGA_RSRC_LEGACY_MEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return "mem";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return "none";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static int vga_str_to_iostate(char *buf, int str_size, int *io_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /* we could in theory hand out locks on IO and mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * separately to userspace but it can cause deadlocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (strncmp(buf, "none", 4) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) *io_state = VGA_RSRC_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /* XXX We're not chekcing the str_size! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (strncmp(buf, "io+mem", 6) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) goto both;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) else if (strncmp(buf, "io", 2) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) goto both;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) else if (strncmp(buf, "mem", 3) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) goto both;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) both:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) *io_state = VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /* this is only used a cookie - it should not be dereferenced */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static struct pci_dev *vga_default;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static void vga_arb_device_card_gone(struct pci_dev *pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /* Find somebody in our list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static struct vga_device *vgadev_find(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct vga_device *vgadev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) list_for_each_entry(vgadev, &vga_list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (pdev == vgadev->pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return vgadev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * vga_default_device - return the default VGA device, for vgacon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * This can be defined by the platform. The default implementation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * is rather dumb and will probably only work properly on single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * vga card setups and/or x86 platforms.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * If your VGA default device is not PCI, you'll have to return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * NULL here. In this case, I assume it will not conflict with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * any PCI card. If this is not true, I'll have to define two archs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * hooks for enabling/disabling the VGA default device if that is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * possible. This may be a problem with real _ISA_ VGA cards, in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * addition to a PCI one. I don't know at this point how to deal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * with that card. Can theirs IOs be disabled at all ? If not, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * I suppose it's a matter of having the proper arch hook telling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * us about it, so we basically never allow anybody to succeed a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * vga_get()...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct pci_dev *vga_default_device(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return vga_default;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) EXPORT_SYMBOL_GPL(vga_default_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) void vga_set_default_device(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (vga_default == pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) pci_dev_put(vga_default);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) vga_default = pci_dev_get(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * vga_remove_vgacon - deactivete vga console
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * Unbind and unregister vgacon in case pdev is the default vga
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * device. Can be called by gpu drivers on initialization to make
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * sure vga register access done by vgacon will not disturb the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * @pdev: pci device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) #if !defined(CONFIG_VGA_CONSOLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) int vga_remove_vgacon(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) #elif !defined(CONFIG_DUMMY_CONSOLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) int vga_remove_vgacon(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) int vga_remove_vgacon(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (pdev != vga_default)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) vgaarb_info(&pdev->dev, "deactivate vga console\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) console_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (con_is_bound(&vga_con))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) ret = do_take_over_console(&dummy_con, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) MAX_NR_CONSOLES - 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ret = do_unregister_con_driver(&vga_con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /* Ignore "already unregistered". */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (ret == -ENODEV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) console_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) EXPORT_SYMBOL(vga_remove_vgacon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) static inline void vga_irq_set_state(struct vga_device *vgadev, bool state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) if (vgadev->irq_set_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) vgadev->irq_set_state(vgadev->cookie, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) /* If we don't ever use VGA arb we should avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) turning off anything anywhere due to old X servers getting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) confused about the boot device not being VGA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) static void vga_check_first_use(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) /* we should inform all GPUs in the system that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * VGA arb has occurred and to try and disable resources
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * if they can */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (!vga_arbiter_used) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) vga_arbiter_used = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) vga_arbiter_notify_clients();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static struct vga_device *__vga_tryget(struct vga_device *vgadev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) unsigned int rsrc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) struct device *dev = &vgadev->pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) unsigned int wants, legacy_wants, match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) struct vga_device *conflict;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) unsigned int pci_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) u32 flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /* Account for "normal" resources to lock. If we decode the legacy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * counterpart, we need to request it as well
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if ((rsrc & VGA_RSRC_NORMAL_IO) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) (vgadev->decodes & VGA_RSRC_LEGACY_IO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) rsrc |= VGA_RSRC_LEGACY_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if ((rsrc & VGA_RSRC_NORMAL_MEM) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) (vgadev->decodes & VGA_RSRC_LEGACY_MEM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) rsrc |= VGA_RSRC_LEGACY_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) vgaarb_dbg(dev, "%s: %d\n", __func__, rsrc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) vgaarb_dbg(dev, "%s: owns: %d\n", __func__, vgadev->owns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /* Check what resources we need to acquire */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) wants = rsrc & ~vgadev->owns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) /* We already own everything, just mark locked & bye bye */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (wants == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) goto lock_them;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) /* We don't need to request a legacy resource, we just enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * appropriate decoding and go
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) legacy_wants = wants & VGA_RSRC_LEGACY_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (legacy_wants == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) goto enable_them;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) /* Ok, we don't, let's find out how we need to kick off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) list_for_each_entry(conflict, &vga_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) unsigned int lwants = legacy_wants;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) unsigned int change_bridge = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) /* Don't conflict with myself */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (vgadev == conflict)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /* Check if the architecture allows a conflict between those
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) * 2 devices or if they are on separate domains
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (!vga_conflicts(vgadev->pdev, conflict->pdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /* We have a possible conflict. before we go further, we must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * check if we sit on the same bus as the conflicting device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * if we don't, then we must tie both IO and MEM resources
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * together since there is only a single bit controlling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * VGA forwarding on P2P bridges
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (vgadev->pdev->bus != conflict->pdev->bus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) change_bridge = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) lwants = VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) /* Check if the guy has a lock on the resource. If he does,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * return the conflicting entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if (conflict->locks & lwants)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) return conflict;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /* Ok, now check if it owns the resource we want. We can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * lock resources that are not decoded, therefore a device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * can own resources it doesn't decode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) match = lwants & conflict->owns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (!match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) /* looks like he doesn't have a lock, we can steal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * them from him
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) pci_bits = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) /* If we can't control legacy resources via the bridge, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * also need to disable normal decoding.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (!conflict->bridge_has_one_vga) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) if ((match & conflict->decodes) & VGA_RSRC_LEGACY_MEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) pci_bits |= PCI_COMMAND_MEMORY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if ((match & conflict->decodes) & VGA_RSRC_LEGACY_IO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) pci_bits |= PCI_COMMAND_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (pci_bits) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) vga_irq_set_state(conflict, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) flags |= PCI_VGA_STATE_CHANGE_DECODES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (change_bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) flags |= PCI_VGA_STATE_CHANGE_BRIDGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) pci_set_vga_state(conflict->pdev, false, pci_bits, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) conflict->owns &= ~match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) /* If we disabled normal decoding, reflect it in owns */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (pci_bits & PCI_COMMAND_MEMORY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) conflict->owns &= ~VGA_RSRC_NORMAL_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (pci_bits & PCI_COMMAND_IO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) conflict->owns &= ~VGA_RSRC_NORMAL_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) enable_them:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) /* ok dude, we got it, everybody conflicting has been disabled, let's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) * enable us. Mark any bits in "owns" regardless of whether we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * decoded them. We can lock resources we don't decode, therefore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * we must track them via "owns".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) pci_bits = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (!vgadev->bridge_has_one_vga) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) flags |= PCI_VGA_STATE_CHANGE_DECODES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (wants & (VGA_RSRC_LEGACY_MEM|VGA_RSRC_NORMAL_MEM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) pci_bits |= PCI_COMMAND_MEMORY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (wants & (VGA_RSRC_LEGACY_IO|VGA_RSRC_NORMAL_IO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) pci_bits |= PCI_COMMAND_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (wants & VGA_RSRC_LEGACY_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) flags |= PCI_VGA_STATE_CHANGE_BRIDGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) pci_set_vga_state(vgadev->pdev, true, pci_bits, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (!vgadev->bridge_has_one_vga)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) vga_irq_set_state(vgadev, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) vgadev->owns |= wants;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) lock_them:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) vgadev->locks |= (rsrc & VGA_RSRC_LEGACY_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (rsrc & VGA_RSRC_LEGACY_IO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) vgadev->io_lock_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (rsrc & VGA_RSRC_LEGACY_MEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) vgadev->mem_lock_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (rsrc & VGA_RSRC_NORMAL_IO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) vgadev->io_norm_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (rsrc & VGA_RSRC_NORMAL_MEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) vgadev->mem_norm_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) static void __vga_put(struct vga_device *vgadev, unsigned int rsrc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) struct device *dev = &vgadev->pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) unsigned int old_locks = vgadev->locks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) vgaarb_dbg(dev, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) /* Update our counters, and account for equivalent legacy resources
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * if we decode them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if ((rsrc & VGA_RSRC_NORMAL_IO) && vgadev->io_norm_cnt > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) vgadev->io_norm_cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (vgadev->decodes & VGA_RSRC_LEGACY_IO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) rsrc |= VGA_RSRC_LEGACY_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if ((rsrc & VGA_RSRC_NORMAL_MEM) && vgadev->mem_norm_cnt > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) vgadev->mem_norm_cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (vgadev->decodes & VGA_RSRC_LEGACY_MEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) rsrc |= VGA_RSRC_LEGACY_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if ((rsrc & VGA_RSRC_LEGACY_IO) && vgadev->io_lock_cnt > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) vgadev->io_lock_cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if ((rsrc & VGA_RSRC_LEGACY_MEM) && vgadev->mem_lock_cnt > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) vgadev->mem_lock_cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /* Just clear lock bits, we do lazy operations so we don't really
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) * have to bother about anything else at this point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (vgadev->io_lock_cnt == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) vgadev->locks &= ~VGA_RSRC_LEGACY_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (vgadev->mem_lock_cnt == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) vgadev->locks &= ~VGA_RSRC_LEGACY_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) /* Kick the wait queue in case somebody was waiting if we actually
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) * released something
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (old_locks != vgadev->locks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) wake_up_all(&vga_wait_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) * vga_get - acquire & locks VGA resources
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) * @pdev: pci device of the VGA card or NULL for the system default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) * @rsrc: bit mask of resources to acquire and lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) * @interruptible: blocking should be interruptible by signals ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) * This function acquires VGA resources for the given card and mark those
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) * resources locked. If the resource requested are "normal" (and not legacy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) * resources, the arbiter will first check whether the card is doing legacy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) * decoding for that type of resource. If yes, the lock is "converted" into a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) * legacy resource lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) * The arbiter will first look for all VGA cards that might conflict and disable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) * their IOs and/or Memory access, including VGA forwarding on P2P bridges if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) * necessary, so that the requested resources can be used. Then, the card is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) * marked as locking these resources and the IO and/or Memory accesses are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) * enabled on the card (including VGA forwarding on parent P2P bridges if any).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * This function will block if some conflicting card is already locking one of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * the required resources (or any resource on a different bus segment, since P2P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) * bridges don't differentiate VGA memory and IO afaik). You can indicate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * whether this blocking should be interruptible by a signal (for userland
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) * interface) or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) * Must not be called at interrupt time or in atomic context. If the card
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) * already owns the resources, the function succeeds. Nested calls are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * supported (a per-resource counter is maintained)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) * On success, release the VGA resource again with vga_put().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) * 0 on success, negative error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) int vga_get(struct pci_dev *pdev, unsigned int rsrc, int interruptible)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) struct vga_device *vgadev, *conflict;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) wait_queue_entry_t wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) vga_check_first_use();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) /* The one who calls us should check for this, but lets be sure... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (pdev == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) pdev = vga_default_device();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (pdev == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) spin_lock_irqsave(&vga_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) vgadev = vgadev_find(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (vgadev == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) spin_unlock_irqrestore(&vga_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) conflict = __vga_tryget(vgadev, rsrc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) spin_unlock_irqrestore(&vga_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (conflict == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) /* We have a conflict, we wait until somebody kicks the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) * work queue. Currently we have one work queue that we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) * kick each time some resources are released, but it would
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) * be fairly easy to have a per device one so that we only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) * need to attach to the conflicting device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) init_waitqueue_entry(&wait, current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) add_wait_queue(&vga_wait_queue, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) set_current_state(interruptible ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) TASK_INTERRUPTIBLE :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) TASK_UNINTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (interruptible && signal_pending(current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) __set_current_state(TASK_RUNNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) remove_wait_queue(&vga_wait_queue, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) rc = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) remove_wait_queue(&vga_wait_queue, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) EXPORT_SYMBOL(vga_get);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) * vga_tryget - try to acquire & lock legacy VGA resources
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) * @pdev: pci devivce of VGA card or NULL for system default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) * @rsrc: bit mask of resources to acquire and lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) * This function performs the same operation as vga_get(), but will return an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) * error (-EBUSY) instead of blocking if the resources are already locked by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) * another card. It can be called in any context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) * On success, release the VGA resource again with vga_put().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) * 0 on success, negative error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) static int vga_tryget(struct pci_dev *pdev, unsigned int rsrc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) struct vga_device *vgadev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) vga_check_first_use();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) /* The one who calls us should check for this, but lets be sure... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (pdev == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) pdev = vga_default_device();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) if (pdev == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) spin_lock_irqsave(&vga_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) vgadev = vgadev_find(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (vgadev == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (__vga_tryget(vgadev, rsrc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) rc = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) bail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) spin_unlock_irqrestore(&vga_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) * vga_put - release lock on legacy VGA resources
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) * @pdev: pci device of VGA card or NULL for system default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * @rsrc: but mask of resource to release
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) * This fuction releases resources previously locked by vga_get() or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) * vga_tryget(). The resources aren't disabled right away, so that a subsequence
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) * vga_get() on the same card will succeed immediately. Resources have a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) * counter, so locks are only released if the counter reaches 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) void vga_put(struct pci_dev *pdev, unsigned int rsrc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) struct vga_device *vgadev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) /* The one who calls us should check for this, but lets be sure... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) if (pdev == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) pdev = vga_default_device();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) if (pdev == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) spin_lock_irqsave(&vga_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) vgadev = vgadev_find(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (vgadev == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) __vga_put(vgadev, rsrc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) bail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) spin_unlock_irqrestore(&vga_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) EXPORT_SYMBOL(vga_put);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) * Rules for using a bridge to control a VGA descendant decoding: if a bridge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) * has only one VGA descendant then it can be used to control the VGA routing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) * for that device. It should always use the bridge closest to the device to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) * control it. If a bridge has a direct VGA descendant, but also have a sub-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) * bridge VGA descendant then we cannot use that bridge to control the direct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) * VGA descendant. So for every device we register, we need to iterate all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) * its parent bridges so we can invalidate any devices using them properly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) static void vga_arbiter_check_bridge_sharing(struct vga_device *vgadev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) struct vga_device *same_bridge_vgadev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) struct pci_bus *new_bus, *bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) struct pci_dev *new_bridge, *bridge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) vgadev->bridge_has_one_vga = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (list_empty(&vga_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) /* okay iterate the new devices bridge hierarachy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) new_bus = vgadev->pdev->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) while (new_bus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) new_bridge = new_bus->self;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) /* go through list of devices already registered */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) list_for_each_entry(same_bridge_vgadev, &vga_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) bus = same_bridge_vgadev->pdev->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) bridge = bus->self;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) /* see if the share a bridge with this device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) if (new_bridge == bridge) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) * If their direct parent bridge is the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) * as any bridge of this device then it can't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) * be used for that device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) same_bridge_vgadev->bridge_has_one_vga = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) * Now iterate the previous devices bridge hierarchy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) * If the new devices parent bridge is in the other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) * devices hierarchy then we can't use it to control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) * this device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) while (bus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) bridge = bus->self;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) if (bridge && bridge == vgadev->pdev->bus->self)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) vgadev->bridge_has_one_vga = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) bus = bus->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) new_bus = new_bus->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) * Currently, we assume that the "initial" setup of the system is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) * not sane, that is we come up with conflicting devices and let
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) * the arbiter's client decides if devices decodes or not legacy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) * things.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) static bool vga_arbiter_add_pci_device(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) struct vga_device *vgadev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) struct pci_bus *bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) struct pci_dev *bridge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) u16 cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) /* Only deal with VGA class devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) /* Allocate structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) vgadev = kzalloc(sizeof(struct vga_device), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (vgadev == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) vgaarb_err(&pdev->dev, "failed to allocate VGA arbiter data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) * What to do on allocation failure ? For now, let's just do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) * nothing, I'm not sure there is anything saner to be done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) /* Take lock & check for duplicates */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) spin_lock_irqsave(&vga_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) if (vgadev_find(pdev) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) BUG_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) vgadev->pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) /* By default, assume we decode everything */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) vgadev->decodes = VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) /* by default mark it as decoding */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) vga_decode_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) /* Mark that we "own" resources based on our enables, we will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) * clear that below if the bridge isn't forwarding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) pci_read_config_word(pdev, PCI_COMMAND, &cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) if (cmd & PCI_COMMAND_IO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) vgadev->owns |= VGA_RSRC_LEGACY_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) if (cmd & PCI_COMMAND_MEMORY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) vgadev->owns |= VGA_RSRC_LEGACY_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) /* Check if VGA cycles can get down to us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) bus = pdev->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) while (bus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) bridge = bus->self;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (bridge) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) u16 l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, &l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (!(l & PCI_BRIDGE_CTL_VGA)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) vgadev->owns = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) bus = bus->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) /* Deal with VGA default device. Use first enabled one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) * by default if arch doesn't have it's own hook
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) if (vga_default == NULL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) ((vgadev->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) vgaarb_info(&pdev->dev, "setting as boot VGA device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) vga_set_default_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) vga_arbiter_check_bridge_sharing(vgadev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) /* Add to the list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) list_add_tail(&vgadev->list, &vga_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) vga_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) vgaarb_info(&pdev->dev, "VGA device added: decodes=%s,owns=%s,locks=%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) vga_iostate_to_str(vgadev->decodes),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) vga_iostate_to_str(vgadev->owns),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) vga_iostate_to_str(vgadev->locks));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) spin_unlock_irqrestore(&vga_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) spin_unlock_irqrestore(&vga_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) kfree(vgadev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) static bool vga_arbiter_del_pci_device(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) struct vga_device *vgadev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) bool ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) spin_lock_irqsave(&vga_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) vgadev = vgadev_find(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) if (vgadev == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) if (vga_default == pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) vga_set_default_device(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) if (vgadev->decodes & (VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) vga_decode_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) /* Remove entry from list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) list_del(&vgadev->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) vga_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) /* Notify userland driver that the device is gone so it discards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) * it's copies of the pci_dev pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) vga_arb_device_card_gone(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) /* Wake up all possible waiters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) wake_up_all(&vga_wait_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) bail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) spin_unlock_irqrestore(&vga_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) kfree(vgadev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) /* this is called with the lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) static inline void vga_update_device_decodes(struct vga_device *vgadev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) int new_decodes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) struct device *dev = &vgadev->pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) int old_decodes, decodes_removed, decodes_unlocked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) old_decodes = vgadev->decodes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) decodes_removed = ~new_decodes & old_decodes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) decodes_unlocked = vgadev->locks & decodes_removed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) vgadev->decodes = new_decodes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) vgaarb_info(dev, "changed VGA decodes: olddecodes=%s,decodes=%s:owns=%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) vga_iostate_to_str(old_decodes),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) vga_iostate_to_str(vgadev->decodes),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) vga_iostate_to_str(vgadev->owns));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) /* if we removed locked decodes, lock count goes to zero, and release */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) if (decodes_unlocked) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) if (decodes_unlocked & VGA_RSRC_LEGACY_IO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) vgadev->io_lock_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (decodes_unlocked & VGA_RSRC_LEGACY_MEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) vgadev->mem_lock_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) __vga_put(vgadev, decodes_unlocked);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) /* change decodes counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) if (old_decodes & VGA_RSRC_LEGACY_MASK &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) !(new_decodes & VGA_RSRC_LEGACY_MASK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) vga_decode_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) if (!(old_decodes & VGA_RSRC_LEGACY_MASK) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) new_decodes & VGA_RSRC_LEGACY_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) vga_decode_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) vgaarb_dbg(dev, "decoding count now is: %d\n", vga_decode_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) static void __vga_set_legacy_decoding(struct pci_dev *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) unsigned int decodes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) bool userspace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) struct vga_device *vgadev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) decodes &= VGA_RSRC_LEGACY_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) spin_lock_irqsave(&vga_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) vgadev = vgadev_find(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) if (vgadev == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) /* don't let userspace futz with kernel driver decodes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) if (userspace && vgadev->set_vga_decode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) /* update the device decodes + counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) vga_update_device_decodes(vgadev, decodes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) /* XXX if somebody is going from "doesn't decode" to "decodes" state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) * here, additional care must be taken as we may have pending owner
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) * ship of non-legacy region ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) bail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) spin_unlock_irqrestore(&vga_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) void vga_set_legacy_decoding(struct pci_dev *pdev, unsigned int decodes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) __vga_set_legacy_decoding(pdev, decodes, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) EXPORT_SYMBOL(vga_set_legacy_decoding);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) * vga_client_register - register or unregister a VGA arbitration client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) * @pdev: pci device of the VGA client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) * @cookie: client cookie to be used in callbacks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) * @irq_set_state: irq state change callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) * @set_vga_decode: vga decode change callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) * Clients have two callback mechanisms they can use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) * @irq_set_state callback: If a client can't disable its GPUs VGA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) * resources, then we need to be able to ask it to turn off its irqs when we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) * turn off its mem and io decoding.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) * @set_vga_decode callback: If a client can disable its GPU VGA resource, it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) * will get a callback from this to set the encode/decode state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) * Rationale: we cannot disable VGA decode resources unconditionally some single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) * GPU laptops seem to require ACPI or BIOS access to the VGA registers to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) * control things like backlights etc. Hopefully newer multi-GPU laptops do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) * something saner, and desktops won't have any special ACPI for this. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) * driver will get a callback when VGA arbitration is first used by userspace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) * since some older X servers have issues.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) * This function does not check whether a client for @pdev has been registered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) * already.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) * To unregister just call this function with @irq_set_state and @set_vga_decode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) * both set to NULL for the same @pdev as originally used to register them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) * Returns: 0 on success, -1 on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) int vga_client_register(struct pci_dev *pdev, void *cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) void (*irq_set_state)(void *cookie, bool state),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) unsigned int (*set_vga_decode)(void *cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) bool decode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) int ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) struct vga_device *vgadev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) spin_lock_irqsave(&vga_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) vgadev = vgadev_find(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) if (!vgadev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) vgadev->irq_set_state = irq_set_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) vgadev->set_vga_decode = set_vga_decode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) vgadev->cookie = cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) bail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) spin_unlock_irqrestore(&vga_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) EXPORT_SYMBOL(vga_client_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) * Char driver implementation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) * Semantics is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) * open : open user instance of the arbitrer. by default, it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) * attached to the default VGA device of the system.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) * close : close user instance, release locks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) * read : return a string indicating the status of the target.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) * an IO state string is of the form {io,mem,io+mem,none},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) * mc and ic are respectively mem and io lock counts (for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) * debugging/diagnostic only). "decodes" indicate what the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) * card currently decodes, "owns" indicates what is currently
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) * enabled on it, and "locks" indicates what is locked by this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) * card. If the card is unplugged, we get "invalid" then for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) * card_ID and an -ENODEV error is returned for any command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) * until a new card is targeted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) * "<card_ID>,decodes=<io_state>,owns=<io_state>,locks=<io_state> (ic,mc)"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) * write : write a command to the arbiter. List of commands is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) * target <card_ID> : switch target to card <card_ID> (see below)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) * lock <io_state> : acquires locks on target ("none" is invalid io_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) * trylock <io_state> : non-blocking acquire locks on target
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) * unlock <io_state> : release locks on target
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) * unlock all : release all locks on target held by this user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) * decodes <io_state> : set the legacy decoding attributes for the card
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) * poll : event if something change on any card (not just the target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) * card_ID is of the form "PCI:domain:bus:dev.fn". It can be set to "default"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) * to go back to the system default card (TODO: not implemented yet).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) * Currently, only PCI is supported as a prefix, but the userland API may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) * support other bus types in the future, even if the current kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) * implementation doesn't.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) * Note about locks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) * The driver keeps track of which user has what locks on which card. It
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) * supports stacking, like the kernel one. This complexifies the implementation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) * a bit, but makes the arbiter more tolerant to userspace problems and able
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) * to properly cleanup in all cases when a process dies.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) * Currently, a max of 16 cards simultaneously can have locks issued from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) * userspace for a given user (file descriptor instance) of the arbiter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) * If the device is hot-unplugged, there is a hook inside the module to notify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) * they being added/removed in the system and automatically added/removed in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) * the arbiter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) #define MAX_USER_CARDS CONFIG_VGA_ARB_MAX_GPUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) #define PCI_INVALID_CARD ((struct pci_dev *)-1UL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) * Each user has an array of these, tracking which cards have locks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) struct vga_arb_user_card {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) struct pci_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) unsigned int mem_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) unsigned int io_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) struct vga_arb_private {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) struct pci_dev *target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) struct vga_arb_user_card cards[MAX_USER_CARDS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) static LIST_HEAD(vga_user_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) static DEFINE_SPINLOCK(vga_user_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) * This function gets a string in the format: "PCI:domain:bus:dev.fn" and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) * returns the respective values. If the string is not in this format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) * it returns 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) static int vga_pci_str_to_vars(char *buf, int count, unsigned int *domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) unsigned int *bus, unsigned int *devfn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) unsigned int slot, func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) n = sscanf(buf, "PCI:%x:%x:%x.%x", domain, bus, &slot, &func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if (n != 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) *devfn = PCI_DEVFN(slot, func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) static ssize_t vga_arb_read(struct file *file, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) struct vga_arb_private *priv = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) struct vga_device *vgadev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) struct pci_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) char *lbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) lbuf = kmalloc(1024, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) if (lbuf == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) /* Shields against vga_arb_device_card_gone (pci_dev going
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) * away), and allows access to vga list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) spin_lock_irqsave(&vga_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) /* If we are targeting the default, use it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) pdev = priv->target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) if (pdev == NULL || pdev == PCI_INVALID_CARD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) spin_unlock_irqrestore(&vga_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) len = sprintf(lbuf, "invalid");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) /* Find card vgadev structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) vgadev = vgadev_find(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) if (vgadev == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) /* Wow, it's not in the list, that shouldn't happen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) * let's fix us up and return invalid card
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) if (pdev == priv->target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) vga_arb_device_card_gone(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) spin_unlock_irqrestore(&vga_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) len = sprintf(lbuf, "invalid");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) /* Fill the buffer with infos */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) len = snprintf(lbuf, 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) "count:%d,PCI:%s,decodes=%s,owns=%s,locks=%s(%d:%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) vga_decode_count, pci_name(pdev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) vga_iostate_to_str(vgadev->decodes),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) vga_iostate_to_str(vgadev->owns),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) vga_iostate_to_str(vgadev->locks),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) vgadev->io_lock_cnt, vgadev->mem_lock_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) spin_unlock_irqrestore(&vga_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) /* Copy that to user */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) if (len > count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) len = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) rc = copy_to_user(buf, lbuf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) kfree(lbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) * TODO: To avoid parsing inside kernel and to improve the speed we may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) * consider use ioctl here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) static ssize_t vga_arb_write(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) struct vga_arb_private *priv = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) struct vga_arb_user_card *uc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) struct pci_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) unsigned int io_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) char kbuf[64], *curr_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) size_t remaining = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) int ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) if (count >= sizeof(kbuf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) if (copy_from_user(kbuf, buf, count))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) curr_pos = kbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) kbuf[count] = '\0'; /* Just to make sure... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) if (strncmp(curr_pos, "lock ", 5) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) curr_pos += 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) remaining -= 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) pr_debug("client 0x%p called 'lock'\n", priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) if (!vga_str_to_iostate(curr_pos, remaining, &io_state)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) ret_val = -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) if (io_state == VGA_RSRC_NONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) ret_val = -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) pdev = priv->target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) if (priv->target == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) ret_val = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) vga_get_uninterruptible(pdev, io_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) /* Update the client's locks lists... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) for (i = 0; i < MAX_USER_CARDS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) if (priv->cards[i].pdev == pdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) if (io_state & VGA_RSRC_LEGACY_IO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) priv->cards[i].io_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) if (io_state & VGA_RSRC_LEGACY_MEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) priv->cards[i].mem_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) ret_val = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) } else if (strncmp(curr_pos, "unlock ", 7) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) curr_pos += 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) remaining -= 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) pr_debug("client 0x%p called 'unlock'\n", priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) if (strncmp(curr_pos, "all", 3) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) io_state = VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) if (!vga_str_to_iostate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) (curr_pos, remaining, &io_state)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) ret_val = -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) /* TODO: Add this?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) if (io_state == VGA_RSRC_NONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) ret_val = -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) pdev = priv->target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) if (priv->target == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) ret_val = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) for (i = 0; i < MAX_USER_CARDS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) if (priv->cards[i].pdev == pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) uc = &priv->cards[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) if (!uc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) ret_val = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) if (io_state & VGA_RSRC_LEGACY_IO && uc->io_cnt == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) ret_val = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) if (io_state & VGA_RSRC_LEGACY_MEM && uc->mem_cnt == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) ret_val = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) vga_put(pdev, io_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) if (io_state & VGA_RSRC_LEGACY_IO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) uc->io_cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) if (io_state & VGA_RSRC_LEGACY_MEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) uc->mem_cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) ret_val = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) } else if (strncmp(curr_pos, "trylock ", 8) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) curr_pos += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) remaining -= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) pr_debug("client 0x%p called 'trylock'\n", priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) if (!vga_str_to_iostate(curr_pos, remaining, &io_state)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) ret_val = -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) /* TODO: Add this?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) if (io_state == VGA_RSRC_NONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) ret_val = -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) pdev = priv->target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) if (priv->target == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) ret_val = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) if (vga_tryget(pdev, io_state)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) /* Update the client's locks lists... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) for (i = 0; i < MAX_USER_CARDS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) if (priv->cards[i].pdev == pdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) if (io_state & VGA_RSRC_LEGACY_IO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) priv->cards[i].io_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) if (io_state & VGA_RSRC_LEGACY_MEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) priv->cards[i].mem_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) ret_val = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) ret_val = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) } else if (strncmp(curr_pos, "target ", 7) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) unsigned int domain, bus, devfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) struct vga_device *vgadev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) curr_pos += 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) remaining -= 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) pr_debug("client 0x%p called 'target'\n", priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) /* if target is default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) if (!strncmp(curr_pos, "default", 7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) pdev = pci_dev_get(vga_default_device());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) if (!vga_pci_str_to_vars(curr_pos, remaining,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) &domain, &bus, &devfn)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) ret_val = -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) pdev = pci_get_domain_bus_and_slot(domain, bus, devfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) if (!pdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) pr_debug("invalid PCI address %04x:%02x:%02x.%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) domain, bus, PCI_SLOT(devfn),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) PCI_FUNC(devfn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) ret_val = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) pr_debug("%s ==> %04x:%02x:%02x.%x pdev %p\n", curr_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) domain, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) vgadev = vgadev_find(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) pr_debug("vgadev %p\n", vgadev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) if (vgadev == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) if (pdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) vgaarb_dbg(&pdev->dev, "not a VGA device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) pci_dev_put(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) ret_val = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) priv->target = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) for (i = 0; i < MAX_USER_CARDS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) if (priv->cards[i].pdev == pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) if (priv->cards[i].pdev == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) priv->cards[i].pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) priv->cards[i].io_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) priv->cards[i].mem_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) if (i == MAX_USER_CARDS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) vgaarb_dbg(&pdev->dev, "maximum user cards (%d) number reached, ignoring this one!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) MAX_USER_CARDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) pci_dev_put(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) /* XXX: which value to return? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) ret_val = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) ret_val = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) pci_dev_put(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) } else if (strncmp(curr_pos, "decodes ", 8) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) curr_pos += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) remaining -= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) pr_debug("client 0x%p called 'decodes'\n", priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) if (!vga_str_to_iostate(curr_pos, remaining, &io_state)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) ret_val = -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) pdev = priv->target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) if (priv->target == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) ret_val = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) __vga_set_legacy_decoding(pdev, io_state, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) ret_val = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) /* If we got here, the message written is not part of the protocol! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) static __poll_t vga_arb_fpoll(struct file *file, poll_table *wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) pr_debug("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) poll_wait(file, &vga_wait_queue, wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) return EPOLLIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) static int vga_arb_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) struct vga_arb_private *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) pr_debug("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) priv = kzalloc(sizeof(*priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) if (priv == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) spin_lock_init(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) file->private_data = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) spin_lock_irqsave(&vga_user_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) list_add(&priv->list, &vga_user_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) spin_unlock_irqrestore(&vga_user_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) /* Set the client' lists of locks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) priv->target = vga_default_device(); /* Maybe this is still null! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) priv->cards[0].pdev = priv->target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) priv->cards[0].io_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) priv->cards[0].mem_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) static int vga_arb_release(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) struct vga_arb_private *priv = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) struct vga_arb_user_card *uc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) pr_debug("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) spin_lock_irqsave(&vga_user_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) list_del(&priv->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) for (i = 0; i < MAX_USER_CARDS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) uc = &priv->cards[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) if (uc->pdev == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) vgaarb_dbg(&uc->pdev->dev, "uc->io_cnt == %d, uc->mem_cnt == %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) uc->io_cnt, uc->mem_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) while (uc->io_cnt--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) vga_put(uc->pdev, VGA_RSRC_LEGACY_IO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) while (uc->mem_cnt--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) vga_put(uc->pdev, VGA_RSRC_LEGACY_MEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) spin_unlock_irqrestore(&vga_user_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) kfree(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) static void vga_arb_device_card_gone(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) * callback any registered clients to let them know we have a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) * change in VGA cards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) static void vga_arbiter_notify_clients(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) struct vga_device *vgadev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) uint32_t new_decodes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) bool new_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) if (!vga_arbiter_used)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) spin_lock_irqsave(&vga_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) list_for_each_entry(vgadev, &vga_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) if (vga_count > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) new_state = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) new_state = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) if (vgadev->set_vga_decode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) new_decodes = vgadev->set_vga_decode(vgadev->cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) new_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) vga_update_device_decodes(vgadev, new_decodes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) spin_unlock_irqrestore(&vga_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) static int pci_notify(struct notifier_block *nb, unsigned long action,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) struct device *dev = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) struct pci_dev *pdev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) bool notify = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) vgaarb_dbg(dev, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) /* For now we're only intereted in devices added and removed. I didn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) * test this thing here, so someone needs to double check for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) * cases of hotplugable vga cards. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) if (action == BUS_NOTIFY_ADD_DEVICE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) notify = vga_arbiter_add_pci_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) else if (action == BUS_NOTIFY_DEL_DEVICE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) notify = vga_arbiter_del_pci_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) if (notify)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) vga_arbiter_notify_clients();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) static struct notifier_block pci_notifier = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) .notifier_call = pci_notify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) static const struct file_operations vga_arb_device_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) .read = vga_arb_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) .write = vga_arb_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) .poll = vga_arb_fpoll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) .open = vga_arb_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) .release = vga_arb_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) .llseek = noop_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) static struct miscdevice vga_arb_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) MISC_DYNAMIC_MINOR, "vga_arbiter", &vga_arb_device_fops
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) static void __init vga_arb_select_default_device(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) struct pci_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) struct vga_device *vgadev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) #if defined(CONFIG_X86) || defined(CONFIG_IA64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) u64 base = screen_info.lfb_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) u64 size = screen_info.lfb_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) u64 limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) resource_size_t start, end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) base |= (u64)screen_info.ext_lfb_base << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) limit = base + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) list_for_each_entry(vgadev, &vga_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) struct device *dev = &vgadev->pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) * Override vga_arbiter_add_pci_device()'s I/O based detection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) * as it may take the wrong device (e.g. on Apple system under
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) * EFI).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) * Select the device owning the boot framebuffer if there is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) * one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) /* Does firmware framebuffer belong to us? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) flags = pci_resource_flags(vgadev->pdev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) if ((flags & IORESOURCE_MEM) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) start = pci_resource_start(vgadev->pdev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) end = pci_resource_end(vgadev->pdev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) if (!start || !end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) if (base < start || limit >= end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) if (!vga_default_device())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) vgaarb_info(dev, "setting as boot device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) else if (vgadev->pdev != vga_default_device())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) vgaarb_info(dev, "overriding boot device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) vga_set_default_device(vgadev->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) if (!vga_default_device()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) list_for_each_entry(vgadev, &vga_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) struct device *dev = &vgadev->pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) u16 cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) pdev = vgadev->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) pci_read_config_word(pdev, PCI_COMMAND, &cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) if (cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) vgaarb_info(dev, "setting as boot device (VGA legacy resources not available)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) vga_set_default_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) if (!vga_default_device()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) vgadev = list_first_entry_or_null(&vga_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) struct vga_device, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) if (vgadev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) struct device *dev = &vgadev->pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) vgaarb_info(dev, "setting as boot device (VGA legacy resources not available)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) vga_set_default_device(vgadev->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) static int __init vga_arb_device_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) struct pci_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) struct vga_device *vgadev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) rc = misc_register(&vga_arb_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) pr_err("error %d registering device\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) bus_register_notifier(&pci_bus_type, &pci_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) /* We add all PCI devices satisfying VGA class in the arbiter by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) * default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) pdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) while ((pdev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) pci_get_subsys(PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) PCI_ANY_ID, pdev)) != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) vga_arbiter_add_pci_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) list_for_each_entry(vgadev, &vga_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) struct device *dev = &vgadev->pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) if (vgadev->bridge_has_one_vga)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) vgaarb_info(dev, "bridge control possible\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) vgaarb_info(dev, "no bridge control possible\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) vga_arb_select_default_device();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) pr_info("loaded\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) subsys_initcall(vga_arb_device_init);