diff options
-rw-r--r-- | drivers/gpu/Makefile | 2 | ||||
-rw-r--r-- | drivers/gpu/vga/Kconfig | 10 | ||||
-rw-r--r-- | drivers/gpu/vga/Makefile | 1 | ||||
-rw-r--r-- | drivers/gpu/vga/vgaarb.c | 1206 | ||||
-rw-r--r-- | drivers/pci/pci.c | 44 | ||||
-rw-r--r-- | drivers/video/Kconfig | 2 | ||||
-rw-r--r-- | include/linux/pci.h | 2 | ||||
-rw-r--r-- | include/linux/vgaarb.h | 195 |
8 files changed, 1461 insertions, 1 deletions
diff --git a/drivers/gpu/Makefile b/drivers/gpu/Makefile index de566cf0414c..30879df3daea 100644 --- a/drivers/gpu/Makefile +++ b/drivers/gpu/Makefile | |||
@@ -1 +1 @@ | |||
obj-y += drm/ | obj-y += drm/ vga/ | ||
diff --git a/drivers/gpu/vga/Kconfig b/drivers/gpu/vga/Kconfig new file mode 100644 index 000000000000..790e675b13eb --- /dev/null +++ b/drivers/gpu/vga/Kconfig | |||
@@ -0,0 +1,10 @@ | |||
1 | config VGA_ARB | ||
2 | bool "VGA Arbitration" if EMBEDDED | ||
3 | default y | ||
4 | depends on PCI | ||
5 | help | ||
6 | Some "legacy" VGA devices implemented on PCI typically have the same | ||
7 | hard-decoded addresses as they did on ISA. When multiple PCI devices | ||
8 | are accessed at same time they need some kind of coordination. Please | ||
9 | see Documentation/vgaarbiter.txt for more details. Select this to | ||
10 | enable VGA arbiter. | ||
diff --git a/drivers/gpu/vga/Makefile b/drivers/gpu/vga/Makefile new file mode 100644 index 000000000000..7cc8c1ed645b --- /dev/null +++ b/drivers/gpu/vga/Makefile | |||
@@ -0,0 +1 @@ | |||
obj-$(CONFIG_VGA_ARB) += vgaarb.o | |||
diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c new file mode 100644 index 000000000000..199138f241e0 --- /dev/null +++ b/drivers/gpu/vga/vgaarb.c | |||
@@ -0,0 +1,1206 @@ | |||
1 | /* | ||
2 | * vgaarb.c | ||
3 | * | ||
4 | * (C) Copyright 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org> | ||
5 | * (C) Copyright 2007 Paulo R. Zanoni <przanoni@gmail.com> | ||
6 | * (C) Copyright 2007, 2009 Tiago Vignatti <vignatti@freedesktop.org> | ||
7 | * | ||
8 | * Implements the VGA arbitration. For details refer to | ||
9 | * Documentation/vgaarbiter.txt | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/pci.h> | ||
15 | #include <linux/errno.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/list.h> | ||
18 | #include <linux/sched.h> | ||
19 | #include <linux/wait.h> | ||
20 | #include <linux/spinlock.h> | ||
21 | #include <linux/poll.h> | ||
22 | #include <linux/miscdevice.h> | ||
23 | |||
24 | #include <linux/uaccess.h> | ||
25 | |||
26 | #include <linux/vgaarb.h> | ||
27 | |||
28 | static void vga_arbiter_notify_clients(void); | ||
29 | /* | ||
30 | * We keep a list of all vga devices in the system to speed | ||
31 | * up the various operations of the arbiter | ||
32 | */ | ||
33 | struct vga_device { | ||
34 | struct list_head list; | ||
35 | struct pci_dev *pdev; | ||
36 | unsigned int decodes; /* what does it decodes */ | ||
37 | unsigned int owns; /* what does it owns */ | ||
38 | unsigned int locks; /* what does it locks */ | ||
39 | unsigned int io_lock_cnt; /* legacy IO lock count */ | ||
40 | unsigned int mem_lock_cnt; /* legacy MEM lock count */ | ||
41 | unsigned int io_norm_cnt; /* normal IO count */ | ||
42 | unsigned int mem_norm_cnt; /* normal MEM count */ | ||
43 | |||
44 | /* allow IRQ enable/disable hook */ | ||
45 | void *cookie; | ||
46 | void (*irq_set_state)(void *cookie, bool enable); | ||
47 | unsigned int (*set_vga_decode)(void *cookie, bool decode); | ||
48 | }; | ||
49 | |||
50 | static LIST_HEAD(vga_list); | ||
51 | static int vga_count, vga_decode_count; | ||
52 | static bool vga_arbiter_used; | ||
53 | static DEFINE_SPINLOCK(vga_lock); | ||
54 | static DECLARE_WAIT_QUEUE_HEAD(vga_wait_queue); | ||
55 | |||
56 | |||
57 | static const char *vga_iostate_to_str(unsigned int iostate) | ||
58 | { | ||
59 | /* Ignore VGA_RSRC_IO and VGA_RSRC_MEM */ | ||
60 | iostate &= VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM; | ||
61 | switch (iostate) { | ||
62 | case VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM: | ||
63 | return "io+mem"; | ||
64 | case VGA_RSRC_LEGACY_IO: | ||
65 | return "io"; | ||
66 | case VGA_RSRC_LEGACY_MEM: | ||
67 | return "mem"; | ||
68 | } | ||
69 | return "none"; | ||
70 | } | ||
71 | |||
72 | static int vga_str_to_iostate(char *buf, int str_size, int *io_state) | ||
73 | { | ||
74 | /* we could in theory hand out locks on IO and mem | ||
75 | * separately to userspace but it can cause deadlocks */ | ||
76 | if (strncmp(buf, "none", 4) == 0) { | ||
77 | *io_state = VGA_RSRC_NONE; | ||
78 | return 1; | ||
79 | } | ||
80 | |||
81 | /* XXX We're not chekcing the str_size! */ | ||
82 | if (strncmp(buf, "io+mem", 6) == 0) | ||
83 | goto both; | ||
84 | else if (strncmp(buf, "io", 2) == 0) | ||
85 | goto both; | ||
86 | else if (strncmp(buf, "mem", 3) == 0) | ||
87 | goto both; | ||
88 | return 0; | ||
89 | both: | ||
90 | *io_state = VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM; | ||
91 | return 1; | ||
92 | } | ||
93 | |||
94 | #ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE | ||
95 | /* this is only used a cookie - it should not be dereferenced */ | ||
96 | static struct pci_dev *vga_default; | ||
97 | #endif | ||
98 | |||
99 | static void vga_arb_device_card_gone(struct pci_dev *pdev); | ||
100 | |||
101 | /* Find somebody in our list */ | ||
102 | static struct vga_device *vgadev_find(struct pci_dev *pdev) | ||
103 | { | ||
104 | struct vga_device *vgadev; | ||
105 | |||
106 | list_for_each_entry(vgadev, &vga_list, list) | ||
107 | if (pdev == vgadev->pdev) | ||
108 | return vgadev; | ||
109 | return NULL; | ||
110 | } | ||
111 | |||
112 | /* Returns the default VGA device (vgacon's babe) */ | ||
113 | #ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE | ||
114 | struct pci_dev *vga_default_device(void) | ||
115 | { | ||
116 | return vga_default; | ||
117 | } | ||
118 | #endif | ||
119 | |||
120 | static inline void vga_irq_set_state(struct vga_device *vgadev, bool state) | ||
121 | { | ||
122 | if (vgadev->irq_set_state) | ||
123 | vgadev->irq_set_state(vgadev->cookie, state); | ||
124 | } | ||
125 | |||
126 | |||
127 | /* If we don't ever use VGA arb we should avoid | ||
128 | turning off anything anywhere due to old X servers getting | ||
129 | confused about the boot device not being VGA */ | ||
130 | static void vga_check_first_use(void) | ||
131 | { | ||
132 | /* we should inform all GPUs in the system that | ||
133 | * VGA arb has occured and to try and disable resources | ||
134 | * if they can */ | ||
135 | if (!vga_arbiter_used) { | ||
136 | vga_arbiter_used = true; | ||
137 | vga_arbiter_notify_clients(); | ||
138 | } | ||
139 | } | ||
140 | |||
141 | static struct vga_device *__vga_tryget(struct vga_device *vgadev, | ||
142 | unsigned int rsrc) | ||
143 | { | ||
144 | unsigned int wants, legacy_wants, match; | ||
145 | struct vga_device *conflict; | ||
146 | unsigned int pci_bits; | ||
147 | /* Account for "normal" resources to lock. If we decode the legacy, | ||
148 | * counterpart, we need to request it as well | ||
149 | */ | ||
150 | if ((rsrc & VGA_RSRC_NORMAL_IO) && | ||
151 | (vgadev->decodes & VGA_RSRC_LEGACY_IO)) | ||
152 | rsrc |= VGA_RSRC_LEGACY_IO; | ||
153 | if ((rsrc & VGA_RSRC_NORMAL_MEM) && | ||
154 | (vgadev->decodes & VGA_RSRC_LEGACY_MEM)) | ||
155 | rsrc |= VGA_RSRC_LEGACY_MEM; | ||
156 | |||
157 | pr_devel("%s: %d\n", __func__, rsrc); | ||
158 | pr_devel("%s: owns: %d\n", __func__, vgadev->owns); | ||
159 | |||
160 | /* Check what resources we need to acquire */ | ||
161 | wants = rsrc & ~vgadev->owns; | ||
162 | |||
163 | /* We already own everything, just mark locked & bye bye */ | ||
164 | if (wants == 0) | ||
165 | goto lock_them; | ||
166 | |||
167 | /* We don't need to request a legacy resource, we just enable | ||
168 | * appropriate decoding and go | ||
169 | */ | ||
170 | legacy_wants = wants & VGA_RSRC_LEGACY_MASK; | ||
171 | if (legacy_wants == 0) | ||
172 | goto enable_them; | ||
173 | |||
174 | /* Ok, we don't, let's find out how we need to kick off */ | ||
175 | list_for_each_entry(conflict, &vga_list, list) { | ||
176 | unsigned int lwants = legacy_wants; | ||
177 | unsigned int change_bridge = 0; | ||
178 | |||
179 | /* Don't conflict with myself */ | ||
180 | if (vgadev == conflict) | ||
181 | continue; | ||
182 | |||
183 | /* Check if the architecture allows a conflict between those | ||
184 | * 2 devices or if they are on separate domains | ||
185 | */ | ||
186 | if (!vga_conflicts(vgadev->pdev, conflict->pdev)) | ||
187 | continue; | ||
188 | |||
189 | /* We have a possible conflict. before we go further, we must | ||
190 | * check if we sit on the same bus as the conflicting device. | ||
191 | * if we don't, then we must tie both IO and MEM resources | ||
192 | * together since there is only a single bit controlling | ||
193 | * VGA forwarding on P2P bridges | ||
194 | */ | ||
195 | if (vgadev->pdev->bus != conflict->pdev->bus) { | ||
196 | change_bridge = 1; | ||
197 | lwants = VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM; | ||
198 | } | ||
199 | |||
200 | /* Check if the guy has a lock on the resource. If he does, | ||
201 | * return the conflicting entry | ||
202 | */ | ||
203 | if (conflict->locks & lwants) | ||
204 | return conflict; | ||
205 | |||
206 | /* Ok, now check if he owns the resource we want. We don't need | ||
207 | * to check "decodes" since it should be impossible to own | ||
208 | * own legacy resources you don't decode unless I have a bug | ||
209 | * in this code... | ||
210 | */ | ||
211 | WARN_ON(conflict->owns & ~conflict->decodes); | ||
212 | match = lwants & conflict->owns; | ||
213 | if (!match) | ||
214 | continue; | ||
215 | |||
216 | /* looks like he doesn't have a lock, we can steal | ||
217 | * them from him | ||
218 | */ | ||
219 | vga_irq_set_state(conflict, false); | ||
220 | |||
221 | pci_bits = 0; | ||
222 | if (lwants & (VGA_RSRC_LEGACY_MEM|VGA_RSRC_NORMAL_MEM)) | ||
223 | pci_bits |= PCI_COMMAND_MEMORY; | ||
224 | if (lwants & (VGA_RSRC_LEGACY_IO|VGA_RSRC_NORMAL_IO)) | ||
225 | pci_bits |= PCI_COMMAND_IO; | ||
226 | |||
227 | pci_set_vga_state(conflict->pdev, false, pci_bits, | ||
228 | change_bridge); | ||
229 | conflict->owns &= ~lwants; | ||
230 | /* If he also owned non-legacy, that is no longer the case */ | ||
231 | if (lwants & VGA_RSRC_LEGACY_MEM) | ||
232 | conflict->owns &= ~VGA_RSRC_NORMAL_MEM; | ||
233 | if (lwants & VGA_RSRC_LEGACY_IO) | ||
234 | conflict->owns &= ~VGA_RSRC_NORMAL_IO; | ||
235 | } | ||
236 | |||
237 | enable_them: | ||
238 | /* ok dude, we got it, everybody conflicting has been disabled, let's | ||
239 | * enable us. Make sure we don't mark a bit in "owns" that we don't | ||
240 | * also have in "decodes". We can lock resources we don't decode but | ||
241 | * not own them. | ||
242 | */ | ||
243 | pci_bits = 0; | ||
244 | if (wants & (VGA_RSRC_LEGACY_MEM|VGA_RSRC_NORMAL_MEM)) | ||
245 | pci_bits |= PCI_COMMAND_MEMORY; | ||
246 | if (wants & (VGA_RSRC_LEGACY_IO|VGA_RSRC_NORMAL_IO)) | ||
247 | pci_bits |= PCI_COMMAND_IO; | ||
248 | pci_set_vga_state(vgadev->pdev, true, pci_bits, !!(wants & VGA_RSRC_LEGACY_MASK)); | ||
249 | |||
250 | vga_irq_set_state(vgadev, true); | ||
251 | vgadev->owns |= (wants & vgadev->decodes); | ||
252 | lock_them: | ||
253 | vgadev->locks |= (rsrc & VGA_RSRC_LEGACY_MASK); | ||
254 | if (rsrc & VGA_RSRC_LEGACY_IO) | ||
255 | vgadev->io_lock_cnt++; | ||
256 | if (rsrc & VGA_RSRC_LEGACY_MEM) | ||
257 | vgadev->mem_lock_cnt++; | ||
258 | if (rsrc & VGA_RSRC_NORMAL_IO) | ||
259 | vgadev->io_norm_cnt++; | ||
260 | if (rsrc & VGA_RSRC_NORMAL_MEM) | ||
261 | vgadev->mem_norm_cnt++; | ||
262 | |||
263 | return NULL; | ||
264 | } | ||
265 | |||
266 | static void __vga_put(struct vga_device *vgadev, unsigned int rsrc) | ||
267 | { | ||
268 | unsigned int old_locks = vgadev->locks; | ||
269 | |||
270 | pr_devel("%s\n", __func__); | ||
271 | |||
272 | /* Update our counters, and account for equivalent legacy resources | ||
273 | * if we decode them | ||
274 | */ | ||
275 | if ((rsrc & VGA_RSRC_NORMAL_IO) && vgadev->io_norm_cnt > 0) { | ||
276 | vgadev->io_norm_cnt--; | ||
277 | if (vgadev->decodes & VGA_RSRC_LEGACY_IO) | ||
278 | rsrc |= VGA_RSRC_LEGACY_IO; | ||
279 | } | ||
280 | if ((rsrc & VGA_RSRC_NORMAL_MEM) && vgadev->mem_norm_cnt > 0) { | ||
281 | vgadev->mem_norm_cnt--; | ||
282 | if (vgadev->decodes & VGA_RSRC_LEGACY_MEM) | ||
283 | rsrc |= VGA_RSRC_LEGACY_MEM; | ||
284 | } | ||
285 | if ((rsrc & VGA_RSRC_LEGACY_IO) && vgadev->io_lock_cnt > 0) | ||
286 | vgadev->io_lock_cnt--; | ||
287 | if ((rsrc & VGA_RSRC_LEGACY_MEM) && vgadev->mem_lock_cnt > 0) | ||
288 | vgadev->mem_lock_cnt--; | ||
289 | |||
290 | /* Just clear lock bits, we do lazy operations so we don't really | ||
291 | * have to bother about anything else at this point | ||
292 | */ | ||
293 | if (vgadev->io_lock_cnt == 0) | ||
294 | vgadev->locks &= ~VGA_RSRC_LEGACY_IO; | ||
295 | if (vgadev->mem_lock_cnt == 0) | ||
296 | vgadev->locks &= ~VGA_RSRC_LEGACY_MEM; | ||
297 | |||
298 | /* Kick the wait queue in case somebody was waiting if we actually | ||
299 | * released something | ||
300 | */ | ||
301 | if (old_locks != vgadev->locks) | ||
302 | wake_up_all(&vga_wait_queue); | ||
303 | } | ||
304 | |||
305 | int vga_get(struct pci_dev *pdev, unsigned int rsrc, int interruptible) | ||
306 | { | ||
307 | struct vga_device *vgadev, *conflict; | ||
308 | unsigned long flags; | ||
309 | wait_queue_t wait; | ||
310 | int rc = 0; | ||
311 | |||
312 | vga_check_first_use(); | ||
313 | /* The one who calls us should check for this, but lets be sure... */ | ||
314 | if (pdev == NULL) | ||
315 | pdev = vga_default_device(); | ||
316 | if (pdev == NULL) | ||
317 | return 0; | ||
318 | |||
319 | for (;;) { | ||
320 | spin_lock_irqsave(&vga_lock, flags); | ||
321 | vgadev = vgadev_find(pdev); | ||
322 | if (vgadev == NULL) { | ||
323 | spin_unlock_irqrestore(&vga_lock, flags); | ||
324 | rc = -ENODEV; | ||
325 | break; | ||
326 | } | ||
327 | conflict = __vga_tryget(vgadev, rsrc); | ||
328 | spin_unlock_irqrestore(&vga_lock, flags); | ||
329 | if (conflict == NULL) | ||
330 | break; | ||
331 | |||
332 | |||
333 | /* We have a conflict, we wait until somebody kicks the | ||
334 | * work queue. Currently we have one work queue that we | ||
335 | * kick each time some resources are released, but it would | ||
336 | * be fairly easy to have a per device one so that we only | ||
337 | * need to attach to the conflicting device | ||
338 | */ | ||
339 | init_waitqueue_entry(&wait, current); | ||
340 | add_wait_queue(&vga_wait_queue, &wait); | ||
341 | set_current_state(interruptible ? | ||
342 | TASK_INTERRUPTIBLE : | ||
343 | TASK_UNINTERRUPTIBLE); | ||
344 | if (signal_pending(current)) { | ||
345 | rc = -EINTR; | ||
346 | break; | ||
347 | } | ||
348 | schedule(); | ||
349 | remove_wait_queue(&vga_wait_queue, &wait); | ||
350 | set_current_state(TASK_RUNNING); | ||
351 | } | ||
352 | return rc; | ||
353 | } | ||
354 | EXPORT_SYMBOL(vga_get); | ||
355 | |||
356 | int vga_tryget(struct pci_dev *pdev, unsigned int rsrc) | ||
357 | { | ||
358 | struct vga_device *vgadev; | ||
359 | unsigned long flags; | ||
360 | int rc = 0; | ||
361 | |||
362 | vga_check_first_use(); | ||
363 | |||
364 | /* The one who calls us should check for this, but lets be sure... */ | ||
365 | if (pdev == NULL) | ||
366 | pdev = vga_default_device(); | ||
367 | if (pdev == NULL) | ||
368 | return 0; | ||
369 | spin_lock_irqsave(&vga_lock, flags); | ||
370 | vgadev = vgadev_find(pdev); | ||
371 | if (vgadev == NULL) { | ||
372 | rc = -ENODEV; | ||
373 | goto bail; | ||
374 | } | ||
375 | if (__vga_tryget(vgadev, rsrc)) | ||
376 | rc = -EBUSY; | ||
377 | bail: | ||
378 | spin_unlock_irqrestore(&vga_lock, flags); | ||
379 | return rc; | ||
380 | } | ||
381 | EXPORT_SYMBOL(vga_tryget); | ||
382 | |||
383 | void vga_put(struct pci_dev *pdev, unsigned int rsrc) | ||
384 | { | ||
385 | struct vga_device *vgadev; | ||
386 | unsigned long flags; | ||
387 | |||
388 | /* The one who calls us should check for this, but lets be sure... */ | ||
389 | if (pdev == NULL) | ||
390 | pdev = vga_default_device(); | ||
391 | if (pdev == NULL) | ||
392 | return; | ||
393 | spin_lock_irqsave(&vga_lock, flags); | ||
394 | vgadev = vgadev_find(pdev); | ||
395 | if (vgadev == NULL) | ||
396 | goto bail; | ||
397 | __vga_put(vgadev, rsrc); | ||
398 | bail: | ||
399 | spin_unlock_irqrestore(&vga_lock, flags); | ||
400 | } | ||
401 | EXPORT_SYMBOL(vga_put); | ||
402 | |||
403 | /* | ||
404 | * Currently, we assume that the "initial" setup of the system is | ||
405 | * not sane, that is we come up with conflicting devices and let | ||
406 | * the arbiter's client decides if devices decodes or not legacy | ||
407 | * things. | ||
408 | */ | ||
409 | static bool vga_arbiter_add_pci_device(struct pci_dev *pdev) | ||
410 | { | ||
411 | struct vga_device *vgadev; | ||
412 | unsigned long flags; | ||
413 | struct pci_bus *bus; | ||
414 | struct pci_dev *bridge; | ||
415 | u16 cmd; | ||
416 | |||
417 | /* Only deal with VGA class devices */ | ||
418 | if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA) | ||
419 | return false; | ||
420 | |||
421 | /* Allocate structure */ | ||
422 | vgadev = kmalloc(sizeof(struct vga_device), GFP_KERNEL); | ||
423 | if (vgadev == NULL) { | ||
424 | pr_err("vgaarb: failed to allocate pci device\n"); | ||
425 | /* What to do on allocation failure ? For now, let's | ||
426 | * just do nothing, I'm not sure there is anything saner | ||
427 | * to be done | ||
428 | */ | ||
429 | return false; | ||
430 | } | ||
431 | |||
432 | memset(vgadev, 0, sizeof(*vgadev)); | ||
433 | |||
434 | /* Take lock & check for duplicates */ | ||
435 | spin_lock_irqsave(&vga_lock, flags); | ||
436 | if (vgadev_find(pdev) != NULL) { | ||
437 | BUG_ON(1); | ||
438 | goto fail; | ||
439 | } | ||
440 | vgadev->pdev = pdev; | ||
441 | |||
442 | /* By default, assume we decode everything */ | ||
443 | vgadev->decodes = VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM | | ||
444 | VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; | ||
445 | |||
446 | /* by default mark it as decoding */ | ||
447 | vga_decode_count++; | ||
448 | /* Mark that we "own" resources based on our enables, we will | ||
449 | * clear that below if the bridge isn't forwarding | ||
450 | */ | ||
451 | pci_read_config_word(pdev, PCI_COMMAND, &cmd); | ||
452 | if (cmd & PCI_COMMAND_IO) | ||
453 | vgadev->owns |= VGA_RSRC_LEGACY_IO; | ||
454 | if (cmd & PCI_COMMAND_MEMORY) | ||
455 | vgadev->owns |= VGA_RSRC_LEGACY_MEM; | ||
456 | |||
457 | /* Check if VGA cycles can get down to us */ | ||
458 | bus = pdev->bus; | ||
459 | while (bus) { | ||
460 | bridge = bus->self; | ||
461 | if (bridge) { | ||
462 | u16 l; | ||
463 | pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, | ||
464 | &l); | ||
465 | if (!(l & PCI_BRIDGE_CTL_VGA)) { | ||
466 | vgadev->owns = 0; | ||
467 | break; | ||
468 | } | ||
469 | } | ||
470 | bus = bus->parent; | ||
471 | } | ||
472 | |||
473 | /* Deal with VGA default device. Use first enabled one | ||
474 | * by default if arch doesn't have it's own hook | ||
475 | */ | ||
476 | #ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE | ||
477 | if (vga_default == NULL && | ||
478 | ((vgadev->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK)) | ||
479 | vga_default = pci_dev_get(pdev); | ||
480 | #endif | ||
481 | |||
482 | /* Add to the list */ | ||
483 | list_add(&vgadev->list, &vga_list); | ||
484 | vga_count++; | ||
485 | pr_info("vgaarb: device added: PCI:%s,decodes=%s,owns=%s,locks=%s\n", | ||
486 | pci_name(pdev), | ||
487 | vga_iostate_to_str(vgadev->decodes), | ||
488 | vga_iostate_to_str(vgadev->owns), | ||
489 | vga_iostate_to_str(vgadev->locks)); | ||
490 | |||
491 | spin_unlock_irqrestore(&vga_lock, flags); | ||
492 | return true; | ||
493 | fail: | ||
494 | spin_unlock_irqrestore(&vga_lock, flags); | ||
495 | kfree(vgadev); | ||
496 | return false; | ||
497 | } | ||
498 | |||
499 | static bool vga_arbiter_del_pci_device(struct pci_dev *pdev) | ||
500 | { | ||
501 | struct vga_device *vgadev; | ||
502 | unsigned long flags; | ||
503 | bool ret = true; | ||
504 | |||
505 | spin_lock_irqsave(&vga_lock, flags); | ||
506 | vgadev = vgadev_find(pdev); | ||
507 | if (vgadev == NULL) { | ||
508 | ret = false; | ||
509 | goto bail; | ||
510 | } | ||
511 | |||
512 | if (vga_default == pdev) { | ||
513 | pci_dev_put(vga_default); | ||
514 | vga_default = NULL; | ||
515 | } | ||
516 | |||
517 | if (vgadev->decodes & (VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM)) | ||
518 | vga_decode_count--; | ||
519 | |||
520 | /* Remove entry from list */ | ||
521 | list_del(&vgadev->list); | ||
522 | vga_count--; | ||
523 | /* Notify userland driver that the device is gone so it discards | ||
524 | * it's copies of the pci_dev pointer | ||
525 | */ | ||
526 | vga_arb_device_card_gone(pdev); | ||
527 | |||
528 | /* Wake up all possible waiters */ | ||
529 | wake_up_all(&vga_wait_queue); | ||
530 | bail: | ||
531 | spin_unlock_irqrestore(&vga_lock, flags); | ||
532 | kfree(vgadev); | ||
533 | return ret; | ||
534 | } | ||
535 | |||
536 | /* this is called with the lock */ | ||
537 | static inline void vga_update_device_decodes(struct vga_device *vgadev, | ||
538 | int new_decodes) | ||
539 | { | ||
540 | int old_decodes; | ||
541 | struct vga_device *new_vgadev, *conflict; | ||
542 | |||
543 | old_decodes = vgadev->decodes; | ||
544 | vgadev->decodes = new_decodes; | ||
545 | |||
546 | pr_info("vgaarb: device changed decodes: PCI:%s,olddecodes=%s,decodes=%s:owns=%s\n", | ||
547 | pci_name(vgadev->pdev), | ||
548 | vga_iostate_to_str(old_decodes), | ||
549 | vga_iostate_to_str(vgadev->decodes), | ||
550 | vga_iostate_to_str(vgadev->owns)); | ||
551 | |||
552 | |||
553 | /* if we own the decodes we should move them along to | ||
554 | another card */ | ||
555 | if ((vgadev->owns & old_decodes) && (vga_count > 1)) { | ||
556 | /* set us to own nothing */ | ||
557 | vgadev->owns &= ~old_decodes; | ||
558 | list_for_each_entry(new_vgadev, &vga_list, list) { | ||
559 | if ((new_vgadev != vgadev) && | ||
560 | (new_vgadev->decodes & VGA_RSRC_LEGACY_MASK)) { | ||
561 | pr_info("vgaarb: transferring owner from PCI:%s to PCI:%s\n", pci_name(vgadev->pdev), pci_name(new_vgadev->pdev)); | ||
562 | conflict = __vga_tryget(new_vgadev, VGA_RSRC_LEGACY_MASK); | ||
563 | if (!conflict) | ||
564 | __vga_put(new_vgadev, VGA_RSRC_LEGACY_MASK); | ||
565 | break; | ||
566 | } | ||
567 | } | ||
568 | } | ||
569 | |||
570 | /* change decodes counter */ | ||
571 | if (old_decodes != new_decodes) { | ||
572 | if (new_decodes & (VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM)) | ||
573 | vga_decode_count++; | ||
574 | else | ||
575 | vga_decode_count--; | ||
576 | } | ||
577 | } | ||
578 | |||
579 | void __vga_set_legacy_decoding(struct pci_dev *pdev, unsigned int decodes, bool userspace) | ||
580 | { | ||
581 | struct vga_device *vgadev; | ||
582 | unsigned long flags; | ||
583 | |||
584 | decodes &= VGA_RSRC_LEGACY_MASK; | ||
585 | |||
586 | spin_lock_irqsave(&vga_lock, flags); | ||
587 | vgadev = vgadev_find(pdev); | ||
588 | if (vgadev == NULL) | ||
589 | goto bail; | ||
590 | |||
591 | /* don't let userspace futz with kernel driver decodes */ | ||
592 | if (userspace && vgadev->set_vga_decode) | ||
593 | goto bail; | ||
594 | |||
595 | /* update the device decodes + counter */ | ||
596 | vga_update_device_decodes(vgadev, decodes); | ||
597 | |||
598 | /* XXX if somebody is going from "doesn't decode" to "decodes" state | ||
599 | * here, additional care must be taken as we may have pending owner | ||
600 | * ship of non-legacy region ... | ||
601 | */ | ||
602 | bail: | ||
603 | spin_unlock_irqrestore(&vga_lock, flags); | ||
604 | } | ||
605 | |||
606 | void vga_set_legacy_decoding(struct pci_dev *pdev, unsigned int decodes) | ||
607 | { | ||
608 | __vga_set_legacy_decoding(pdev, decodes, false); | ||
609 | } | ||
610 | EXPORT_SYMBOL(vga_set_legacy_decoding); | ||
611 | |||
612 | /* return number of active VGA devices */ | ||
613 | /* call with NULL to unregister */ | ||
614 | int vga_client_register(struct pci_dev *pdev, void *cookie, | ||
615 | void (*irq_set_state)(void *cookie, bool state), | ||
616 | unsigned int (*set_vga_decode)(void *cookie, bool decode)) | ||
617 | { | ||
618 | int ret = -1; | ||
619 | struct vga_device *vgadev; | ||
620 | unsigned long flags; | ||
621 | |||
622 | spin_lock_irqsave(&vga_lock, flags); | ||
623 | vgadev = vgadev_find(pdev); | ||
624 | if (!vgadev) | ||
625 | goto bail; | ||
626 | |||
627 | vgadev->irq_set_state = irq_set_state; | ||
628 | vgadev->set_vga_decode = set_vga_decode; | ||
629 | vgadev->cookie = cookie; | ||
630 | ret = 0; | ||
631 | |||
632 | bail: | ||
633 | spin_unlock_irqrestore(&vga_lock, flags); | ||
634 | return ret; | ||
635 | |||
636 | } | ||
637 | EXPORT_SYMBOL(vga_client_register); | ||
638 | |||
639 | /* | ||
640 | * Char driver implementation | ||
641 | * | ||
642 | * Semantics is: | ||
643 | * | ||
644 | * open : open user instance of the arbitrer. by default, it's | ||
645 | * attached to the default VGA device of the system. | ||
646 | * | ||
647 | * close : close user instance, release locks | ||
648 | * | ||
649 | * read : return a string indicating the status of the target. | ||
650 | * an IO state string is of the form {io,mem,io+mem,none}, | ||
651 | * mc and ic are respectively mem and io lock counts (for | ||
652 | * debugging/diagnostic only). "decodes" indicate what the | ||
653 | * card currently decodes, "owns" indicates what is currently | ||
654 | * enabled on it, and "locks" indicates what is locked by this | ||
655 | * card. If the card is unplugged, we get "invalid" then for | ||
656 | * card_ID and an -ENODEV error is returned for any command | ||
657 | * until a new card is targeted | ||
658 | * | ||
659 | * "<card_ID>,decodes=<io_state>,owns=<io_state>,locks=<io_state> (ic,mc)" | ||
660 | * | ||
661 | * write : write a command to the arbiter. List of commands is: | ||
662 | * | ||
663 | * target <card_ID> : switch target to card <card_ID> (see below) | ||
664 | * lock <io_state> : acquires locks on target ("none" is invalid io_state) | ||
665 | * trylock <io_state> : non-blocking acquire locks on target | ||
666 | * unlock <io_state> : release locks on target | ||
667 | * unlock all : release all locks on target held by this user | ||
668 | * decodes <io_state> : set the legacy decoding attributes for the card | ||
669 | * | ||
670 | * poll : event if something change on any card (not just the target) | ||
671 | * | ||
672 | * card_ID is of the form "PCI:domain:bus:dev.fn". It can be set to "default" | ||
673 | * to go back to the system default card (TODO: not implemented yet). | ||
674 | * Currently, only PCI is supported as a prefix, but the userland API may | ||
675 | * support other bus types in the future, even if the current kernel | ||
676 | * implementation doesn't. | ||
677 | * | ||
678 | * Note about locks: | ||
679 | * | ||
680 | * The driver keeps track of which user has what locks on which card. It | ||
681 | * supports stacking, like the kernel one. This complexifies the implementation | ||
682 | * a bit, but makes the arbiter more tolerant to userspace problems and able | ||
683 | * to properly cleanup in all cases when a process dies. | ||
684 | * Currently, a max of 16 cards simultaneously can have locks issued from | ||
685 | * userspace for a given user (file descriptor instance) of the arbiter. | ||
686 | * | ||
687 | * If the device is hot-unplugged, there is a hook inside the module to notify | ||
688 | * they being added/removed in the system and automatically added/removed in | ||
689 | * the arbiter. | ||
690 | */ | ||
691 | |||
692 | #define MAX_USER_CARDS 16 | ||
693 | #define PCI_INVALID_CARD ((struct pci_dev *)-1UL) | ||
694 | |||
695 | /* | ||
696 | * Each user has an array of these, tracking which cards have locks | ||
697 | */ | ||
698 | struct vga_arb_user_card { | ||
699 | struct pci_dev *pdev; | ||
700 | unsigned int mem_cnt; | ||
701 | unsigned int io_cnt; | ||
702 | }; | ||
703 | |||
704 | struct vga_arb_private { | ||
705 | struct list_head list; | ||
706 | struct pci_dev *target; | ||
707 | struct vga_arb_user_card cards[MAX_USER_CARDS]; | ||
708 | spinlock_t lock; | ||
709 | }; | ||
710 | |||
711 | static LIST_HEAD(vga_user_list); | ||
712 | static DEFINE_SPINLOCK(vga_user_lock); | ||
713 | |||
714 | |||
715 | /* | ||
716 | * This function gets a string in the format: "PCI:domain:bus:dev.fn" and | ||
717 | * returns the respective values. If the string is not in this format, | ||
718 | * it returns 0. | ||
719 | */ | ||
720 | static int vga_pci_str_to_vars(char *buf, int count, unsigned int *domain, | ||
721 | unsigned int *bus, unsigned int *devfn) | ||
722 | { | ||
723 | int n; | ||
724 | unsigned int slot, func; | ||
725 | |||
726 | |||
727 | n = sscanf(buf, "PCI:%x:%x:%x.%x", domain, bus, &slot, &func); | ||
728 | if (n != 4) | ||
729 | return 0; | ||
730 | |||
731 | *devfn = PCI_DEVFN(slot, func); | ||
732 | |||
733 | return 1; | ||
734 | } | ||
735 | |||
736 | static ssize_t vga_arb_read(struct file *file, char __user * buf, | ||
737 | size_t count, loff_t *ppos) | ||
738 | { | ||
739 | struct vga_arb_private *priv = file->private_data; | ||
740 | struct vga_device *vgadev; | ||
741 | struct pci_dev *pdev; | ||
742 | unsigned long flags; | ||
743 | size_t len; | ||
744 | int rc; | ||
745 | char *lbuf; | ||
746 | |||
747 | lbuf = kmalloc(1024, GFP_KERNEL); | ||
748 | if (lbuf == NULL) | ||
749 | return -ENOMEM; | ||
750 | |||
751 | /* Shields against vga_arb_device_card_gone (pci_dev going | ||
752 | * away), and allows access to vga list | ||
753 | */ | ||
754 | spin_lock_irqsave(&vga_lock, flags); | ||
755 | |||
756 | /* If we are targetting the default, use it */ | ||
757 | pdev = priv->target; | ||
758 | if (pdev == NULL || pdev == PCI_INVALID_CARD) { | ||
759 | spin_unlock_irqrestore(&vga_lock, flags); | ||
760 | len = sprintf(lbuf, "invalid"); | ||
761 | goto done; | ||
762 | } | ||
763 | |||
764 | /* Find card vgadev structure */ | ||
765 | vgadev = vgadev_find(pdev); | ||
766 | if (vgadev == NULL) { | ||
767 | /* Wow, it's not in the list, that shouldn't happen, | ||
768 | * let's fix us up and return invalid card | ||
769 | */ | ||
770 | if (pdev == priv->target) | ||
771 | vga_arb_device_card_gone(pdev); | ||
772 | spin_unlock_irqrestore(&vga_lock, flags); | ||
773 | len = sprintf(lbuf, "invalid"); | ||
774 | goto done; | ||
775 | } | ||
776 | |||
777 | /* Fill the buffer with infos */ | ||
778 | len = snprintf(lbuf, 1024, | ||
779 | "count:%d,PCI:%s,decodes=%s,owns=%s,locks=%s(%d:%d)\n", | ||
780 | vga_decode_count, pci_name(pdev), | ||
781 | vga_iostate_to_str(vgadev->decodes), | ||
782 | vga_iostate_to_str(vgadev->owns), | ||
783 | vga_iostate_to_str(vgadev->locks), | ||
784 | vgadev->io_lock_cnt, vgadev->mem_lock_cnt); | ||
785 | |||
786 | spin_unlock_irqrestore(&vga_lock, flags); | ||
787 | done: | ||
788 | |||
789 | /* Copy that to user */ | ||
790 | if (len > count) | ||
791 | len = count; | ||
792 | rc = copy_to_user(buf, lbuf, len); | ||
793 | kfree(lbuf); | ||
794 | if (rc) | ||
795 | return -EFAULT; | ||
796 | return len; | ||
797 | } | ||
798 | |||
799 | /* | ||
800 | * TODO: To avoid parsing inside kernel and to improve the speed we may | ||
801 | * consider use ioctl here | ||
802 | */ | ||
803 | static ssize_t vga_arb_write(struct file *file, const char __user * buf, | ||
804 | size_t count, loff_t *ppos) | ||
805 | { | ||
806 | struct vga_arb_private *priv = file->private_data; | ||
807 | struct vga_arb_user_card *uc = NULL; | ||
808 | struct pci_dev *pdev; | ||
809 | |||
810 | unsigned int io_state; | ||
811 | |||
812 | char *kbuf, *curr_pos; | ||
813 | size_t remaining = count; | ||
814 | |||
815 | int ret_val; | ||
816 | int i; | ||
817 | |||
818 | |||
819 | kbuf = kmalloc(count + 1, GFP_KERNEL); | ||
820 | if (!kbuf) | ||
821 | return -ENOMEM; | ||
822 | |||
823 | if (copy_from_user(kbuf, buf, count)) { | ||
824 | kfree(kbuf); | ||
825 | return -EFAULT; | ||
826 | } | ||
827 | curr_pos = kbuf; | ||
828 | kbuf[count] = '\0'; /* Just to make sure... */ | ||
829 | |||
830 | if (strncmp(curr_pos, "lock ", 5) == 0) { | ||
831 | curr_pos += 5; | ||
832 | remaining -= 5; | ||
833 | |||
834 | pr_devel("client 0x%X called 'lock'\n", (int)priv); | ||
835 | |||
836 | if (!vga_str_to_iostate(curr_pos, remaining, &io_state)) { | ||
837 | ret_val = -EPROTO; | ||
838 | goto done; | ||
839 | } | ||
840 | if (io_state == VGA_RSRC_NONE) { | ||
841 | ret_val = -EPROTO; | ||
842 | goto done; | ||
843 | } | ||
844 | |||
845 | pdev = priv->target; | ||
846 | if (priv->target == NULL) { | ||
847 | ret_val = -ENODEV; | ||
848 | goto done; | ||
849 | } | ||
850 | |||
851 | vga_get_uninterruptible(pdev, io_state); | ||
852 | |||
853 | /* Update the client's locks lists... */ | ||
854 | for (i = 0; i < MAX_USER_CARDS; i++) { | ||
855 | if (priv->cards[i].pdev == pdev) { | ||
856 | if (io_state & VGA_RSRC_LEGACY_IO) | ||
857 | priv->cards[i].io_cnt++; | ||
858 | if (io_state & VGA_RSRC_LEGACY_MEM) | ||
859 | priv->cards[i].mem_cnt++; | ||
860 | break; | ||
861 | } | ||
862 | } | ||
863 | |||
864 | ret_val = count; | ||
865 | goto done; | ||
866 | } else if (strncmp(curr_pos, "unlock ", 7) == 0) { | ||
867 | curr_pos += 7; | ||
868 | remaining -= 7; | ||
869 | |||
870 | pr_devel("client 0x%X called 'unlock'\n", (int)priv); | ||
871 | |||
872 | if (strncmp(curr_pos, "all", 3) == 0) | ||
873 | io_state = VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM; | ||
874 | else { | ||
875 | if (!vga_str_to_iostate | ||
876 | (curr_pos, remaining, &io_state)) { | ||
877 | ret_val = -EPROTO; | ||
878 | goto done; | ||
879 | } | ||
880 | /* TODO: Add this? | ||
881 | if (io_state == VGA_RSRC_NONE) { | ||
882 | ret_val = -EPROTO; | ||
883 | goto done; | ||
884 | } | ||
885 | */ | ||
886 | } | ||
887 | |||
888 | pdev = priv->target; | ||
889 | if (priv->target == NULL) { | ||
890 | ret_val = -ENODEV; | ||
891 | goto done; | ||
892 | } | ||
893 | for (i = 0; i < MAX_USER_CARDS; i++) { | ||
894 | if (priv->cards[i].pdev == pdev) | ||
895 | uc = &priv->cards[i]; | ||
896 | } | ||
897 | |||
898 | if (!uc) | ||
899 | return -EINVAL; | ||
900 | |||
901 | if (io_state & VGA_RSRC_LEGACY_IO && uc->io_cnt == 0) | ||
902 | return -EINVAL; | ||
903 | |||
904 | if (io_state & VGA_RSRC_LEGACY_MEM && uc->mem_cnt == 0) | ||
905 | return -EINVAL; | ||
906 | |||
907 | vga_put(pdev, io_state); | ||
908 | |||
909 | if (io_state & VGA_RSRC_LEGACY_IO) | ||
910 | uc->io_cnt--; | ||
911 | if (io_state & VGA_RSRC_LEGACY_MEM) | ||
912 | uc->mem_cnt--; | ||
913 | |||
914 | ret_val = count; | ||
915 | goto done; | ||
916 | } else if (strncmp(curr_pos, "trylock ", 8) == 0) { | ||
917 | curr_pos += 8; | ||
918 | remaining -= 8; | ||
919 | |||
920 | pr_devel("client 0x%X called 'trylock'\n", (int)priv); | ||
921 | |||
922 | if (!vga_str_to_iostate(curr_pos, remaining, &io_state)) { | ||
923 | ret_val = -EPROTO; | ||
924 | goto done; | ||
925 | } | ||
926 | /* TODO: Add this? | ||
927 | if (io_state == VGA_RSRC_NONE) { | ||
928 | ret_val = -EPROTO; | ||
929 | goto done; | ||
930 | } | ||
931 | */ | ||
932 | |||
933 | pdev = priv->target; | ||
934 | if (priv->target == NULL) { | ||
935 | ret_val = -ENODEV; | ||
936 | goto done; | ||
937 | } | ||
938 | |||
939 | if (vga_tryget(pdev, io_state)) { | ||
940 | /* Update the client's locks lists... */ | ||
941 | for (i = 0; i < MAX_USER_CARDS; i++) { | ||
942 | if (priv->cards[i].pdev == pdev) { | ||
943 | if (io_state & VGA_RSRC_LEGACY_IO) | ||
944 | priv->cards[i].io_cnt++; | ||
945 | if (io_state & VGA_RSRC_LEGACY_MEM) | ||
946 | priv->cards[i].mem_cnt++; | ||
947 | break; | ||
948 | } | ||
949 | } | ||
950 | ret_val = count; | ||
951 | goto done; | ||
952 | } else { | ||
953 | ret_val = -EBUSY; | ||
954 | goto done; | ||
955 | } | ||
956 | |||
957 | } else if (strncmp(curr_pos, "target ", 7) == 0) { | ||
958 | unsigned int domain, bus, devfn; | ||
959 | struct vga_device *vgadev; | ||
960 | |||
961 | curr_pos += 7; | ||
962 | remaining -= 7; | ||
963 | pr_devel("client 0x%X called 'target'\n", (int)priv); | ||
964 | /* if target is default */ | ||
965 | if (!strncmp(buf, "default", 7)) | ||
966 | pdev = pci_dev_get(vga_default_device()); | ||
967 | else { | ||
968 | if (!vga_pci_str_to_vars(curr_pos, remaining, | ||
969 | &domain, &bus, &devfn)) { | ||
970 | ret_val = -EPROTO; | ||
971 | goto done; | ||
972 | } | ||
973 | |||
974 | pdev = pci_get_bus_and_slot(bus, devfn); | ||
975 | if (!pdev) { | ||
976 | pr_info("vgaarb: invalid PCI address!\n"); | ||
977 | ret_val = -ENODEV; | ||
978 | goto done; | ||
979 | } | ||
980 | } | ||
981 | |||
982 | vgadev = vgadev_find(pdev); | ||
983 | if (vgadev == NULL) { | ||
984 | pr_info("vgaarb: this pci device is not a vga device\n"); | ||
985 | pci_dev_put(pdev); | ||
986 | ret_val = -ENODEV; | ||
987 | goto done; | ||
988 | } | ||
989 | |||
990 | priv->target = pdev; | ||
991 | for (i = 0; i < MAX_USER_CARDS; i++) { | ||
992 | if (priv->cards[i].pdev == pdev) | ||
993 | break; | ||
994 | if (priv->cards[i].pdev == NULL) { | ||
995 | priv->cards[i].pdev = pdev; | ||
996 | priv->cards[i].io_cnt = 0; | ||
997 | priv->cards[i].mem_cnt = 0; | ||
998 | break; | ||
999 | } | ||
1000 | } | ||
1001 | if (i == MAX_USER_CARDS) { | ||
1002 | pr_err("vgaarb: maximum user cards number reached!\n"); | ||
1003 | pci_dev_put(pdev); | ||
1004 | /* XXX: which value to return? */ | ||
1005 | ret_val = -ENOMEM; | ||
1006 | goto done; | ||
1007 | } | ||
1008 | |||
1009 | ret_val = count; | ||
1010 | pci_dev_put(pdev); | ||
1011 | goto done; | ||
1012 | |||
1013 | |||
1014 | } else if (strncmp(curr_pos, "decodes ", 8) == 0) { | ||
1015 | curr_pos += 8; | ||
1016 | remaining -= 8; | ||
1017 | pr_devel("vgaarb: client 0x%X called 'decodes'\n", (int)priv); | ||
1018 | |||
1019 | if (!vga_str_to_iostate(curr_pos, remaining, &io_state)) { | ||
1020 | ret_val = -EPROTO; | ||
1021 | goto done; | ||
1022 | } | ||
1023 | pdev = priv->target; | ||
1024 | if (priv->target == NULL) { | ||
1025 | ret_val = -ENODEV; | ||
1026 | goto done; | ||
1027 | } | ||
1028 | |||
1029 | __vga_set_legacy_decoding(pdev, io_state, true); | ||
1030 | ret_val = count; | ||
1031 | goto done; | ||
1032 | } | ||
1033 | /* If we got here, the message written is not part of the protocol! */ | ||
1034 | kfree(kbuf); | ||
1035 | return -EPROTO; | ||
1036 | |||
1037 | done: | ||
1038 | kfree(kbuf); | ||
1039 | return ret_val; | ||
1040 | } | ||
1041 | |||
1042 | static unsigned int vga_arb_fpoll(struct file *file, poll_table * wait) | ||
1043 | { | ||
1044 | struct vga_arb_private *priv = file->private_data; | ||
1045 | |||
1046 | pr_devel("%s\n", __func__); | ||
1047 | |||
1048 | if (priv == NULL) | ||
1049 | return -ENODEV; | ||
1050 | poll_wait(file, &vga_wait_queue, wait); | ||
1051 | return POLLIN; | ||
1052 | } | ||
1053 | |||
1054 | static int vga_arb_open(struct inode *inode, struct file *file) | ||
1055 | { | ||
1056 | struct vga_arb_private *priv; | ||
1057 | unsigned long flags; | ||
1058 | |||
1059 | pr_devel("%s\n", __func__); | ||
1060 | |||
1061 | priv = kmalloc(sizeof(struct vga_arb_private), GFP_KERNEL); | ||
1062 | if (priv == NULL) | ||
1063 | return -ENOMEM; | ||
1064 | memset(priv, 0, sizeof(*priv)); | ||
1065 | spin_lock_init(&priv->lock); | ||
1066 | file->private_data = priv; | ||
1067 | |||
1068 | spin_lock_irqsave(&vga_user_lock, flags); | ||
1069 | list_add(&priv->list, &vga_user_list); | ||
1070 | spin_unlock_irqrestore(&vga_user_lock, flags); | ||
1071 | |||
1072 | /* Set the client' lists of locks */ | ||
1073 | priv->target = vga_default_device(); /* Maybe this is still null! */ | ||
1074 | priv->cards[0].pdev = priv->target; | ||
1075 | priv->cards[0].io_cnt = 0; | ||
1076 | priv->cards[0].mem_cnt = 0; | ||
1077 | |||
1078 | |||
1079 | return 0; | ||
1080 | } | ||
1081 | |||
1082 | static int vga_arb_release(struct inode *inode, struct file *file) | ||
1083 | { | ||
1084 | struct vga_arb_private *priv = file->private_data; | ||
1085 | struct vga_arb_user_card *uc; | ||
1086 | unsigned long flags; | ||
1087 | int i; | ||
1088 | |||
1089 | pr_devel("%s\n", __func__); | ||
1090 | |||
1091 | if (priv == NULL) | ||
1092 | return -ENODEV; | ||
1093 | |||
1094 | spin_lock_irqsave(&vga_user_lock, flags); | ||
1095 | list_del(&priv->list); | ||
1096 | for (i = 0; i < MAX_USER_CARDS; i++) { | ||
1097 | uc = &priv->cards[i]; | ||
1098 | if (uc->pdev == NULL) | ||
1099 | continue; | ||
1100 | pr_devel("uc->io_cnt == %d, uc->mem_cnt == %d\n", | ||
1101 | uc->io_cnt, uc->mem_cnt); | ||
1102 | while (uc->io_cnt--) | ||
1103 | vga_put(uc->pdev, VGA_RSRC_LEGACY_IO); | ||
1104 | while (uc->mem_cnt--) | ||
1105 | vga_put(uc->pdev, VGA_RSRC_LEGACY_MEM); | ||
1106 | } | ||
1107 | spin_unlock_irqrestore(&vga_user_lock, flags); | ||
1108 | |||
1109 | kfree(priv); | ||
1110 | |||
1111 | return 0; | ||
1112 | } | ||
1113 | |||
1114 | static void vga_arb_device_card_gone(struct pci_dev *pdev) | ||
1115 | { | ||
1116 | } | ||
1117 | |||
1118 | /* | ||
1119 | * callback any registered clients to let them know we have a | ||
1120 | * change in VGA cards | ||
1121 | */ | ||
1122 | static void vga_arbiter_notify_clients(void) | ||
1123 | { | ||
1124 | struct vga_device *vgadev; | ||
1125 | unsigned long flags; | ||
1126 | uint32_t new_decodes; | ||
1127 | bool new_state; | ||
1128 | |||
1129 | if (!vga_arbiter_used) | ||
1130 | return; | ||
1131 | |||
1132 | spin_lock_irqsave(&vga_lock, flags); | ||
1133 | list_for_each_entry(vgadev, &vga_list, list) { | ||
1134 | if (vga_count > 1) | ||
1135 | new_state = false; | ||
1136 | else | ||
1137 | new_state = true; | ||
1138 | if (vgadev->set_vga_decode) { | ||
1139 | new_decodes = vgadev->set_vga_decode(vgadev->cookie, new_state); | ||
1140 | vga_update_device_decodes(vgadev, new_decodes); | ||
1141 | } | ||
1142 | } | ||
1143 | spin_unlock_irqrestore(&vga_lock, flags); | ||
1144 | } | ||
1145 | |||
1146 | static int pci_notify(struct notifier_block *nb, unsigned long action, | ||
1147 | void *data) | ||
1148 | { | ||
1149 | struct device *dev = data; | ||
1150 | struct pci_dev *pdev = to_pci_dev(dev); | ||
1151 | bool notify = false; | ||
1152 | |||
1153 | pr_devel("%s\n", __func__); | ||
1154 | |||
1155 | /* For now we're only intereted in devices added and removed. I didn't | ||
1156 | * test this thing here, so someone needs to double check for the | ||
1157 | * cases of hotplugable vga cards. */ | ||
1158 | if (action == BUS_NOTIFY_ADD_DEVICE) | ||
1159 | notify = vga_arbiter_add_pci_device(pdev); | ||
1160 | else if (action == BUS_NOTIFY_DEL_DEVICE) | ||
1161 | notify = vga_arbiter_del_pci_device(pdev); | ||
1162 | |||
1163 | if (notify) | ||
1164 | vga_arbiter_notify_clients(); | ||
1165 | return 0; | ||
1166 | } | ||
1167 | |||
1168 | static struct notifier_block pci_notifier = { | ||
1169 | .notifier_call = pci_notify, | ||
1170 | }; | ||
1171 | |||
1172 | static const struct file_operations vga_arb_device_fops = { | ||
1173 | .read = vga_arb_read, | ||
1174 | .write = vga_arb_write, | ||
1175 | .poll = vga_arb_fpoll, | ||
1176 | .open = vga_arb_open, | ||
1177 | .release = vga_arb_release, | ||
1178 | }; | ||
1179 | |||
1180 | static struct miscdevice vga_arb_device = { | ||
1181 | MISC_DYNAMIC_MINOR, "vga_arbiter", &vga_arb_device_fops | ||
1182 | }; | ||
1183 | |||
1184 | static int __init vga_arb_device_init(void) | ||
1185 | { | ||
1186 | int rc; | ||
1187 | struct pci_dev *pdev; | ||
1188 | |||
1189 | rc = misc_register(&vga_arb_device); | ||
1190 | if (rc < 0) | ||
1191 | pr_err("vgaarb: error %d registering device\n", rc); | ||
1192 | |||
1193 | bus_register_notifier(&pci_bus_type, &pci_notifier); | ||
1194 | |||
1195 | /* We add all pci devices satisfying vga class in the arbiter by | ||
1196 | * default */ | ||
1197 | pdev = NULL; | ||
1198 | while ((pdev = | ||
1199 | pci_get_subsys(PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | ||
1200 | PCI_ANY_ID, pdev)) != NULL) | ||
1201 | vga_arbiter_add_pci_device(pdev); | ||
1202 | |||
1203 | pr_info("vgaarb: loaded\n"); | ||
1204 | return rc; | ||
1205 | } | ||
1206 | subsys_initcall(vga_arb_device_init); | ||
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 7d55039ffa05..bd993351db45 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -2520,6 +2520,50 @@ int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type) | |||
2520 | return 0; | 2520 | return 0; |
2521 | } | 2521 | } |
2522 | 2522 | ||
2523 | /** | ||
2524 | * pci_set_vga_state - set VGA decode state on device and parents if requested | ||
2525 | * @dev the PCI device | ||
2526 | * @decode - true = enable decoding, false = disable decoding | ||
2527 | * @command_bits PCI_COMMAND_IO and/or PCI_COMMAND_MEMORY | ||
2528 | * @change_bridge - traverse ancestors and change bridges | ||
2529 | */ | ||
2530 | int pci_set_vga_state(struct pci_dev *dev, bool decode, | ||
2531 | unsigned int command_bits, bool change_bridge) | ||
2532 | { | ||
2533 | struct pci_bus *bus; | ||
2534 | struct pci_dev *bridge; | ||
2535 | u16 cmd; | ||
2536 | |||
2537 | WARN_ON(command_bits & ~(PCI_COMMAND_IO|PCI_COMMAND_MEMORY)); | ||
2538 | |||
2539 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | ||
2540 | if (decode == true) | ||
2541 | cmd |= command_bits; | ||
2542 | else | ||
2543 | cmd &= ~command_bits; | ||
2544 | pci_write_config_word(dev, PCI_COMMAND, cmd); | ||
2545 | |||
2546 | if (change_bridge == false) | ||
2547 | return 0; | ||
2548 | |||
2549 | bus = dev->bus; | ||
2550 | while (bus) { | ||
2551 | bridge = bus->self; | ||
2552 | if (bridge) { | ||
2553 | pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, | ||
2554 | &cmd); | ||
2555 | if (decode == true) | ||
2556 | cmd |= PCI_BRIDGE_CTL_VGA; | ||
2557 | else | ||
2558 | cmd &= ~PCI_BRIDGE_CTL_VGA; | ||
2559 | pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, | ||
2560 | cmd); | ||
2561 | } | ||
2562 | bus = bus->parent; | ||
2563 | } | ||
2564 | return 0; | ||
2565 | } | ||
2566 | |||
2523 | #define RESOURCE_ALIGNMENT_PARAM_SIZE COMMAND_LINE_SIZE | 2567 | #define RESOURCE_ALIGNMENT_PARAM_SIZE COMMAND_LINE_SIZE |
2524 | static char resource_alignment_param[RESOURCE_ALIGNMENT_PARAM_SIZE] = {0}; | 2568 | static char resource_alignment_param[RESOURCE_ALIGNMENT_PARAM_SIZE] = {0}; |
2525 | spinlock_t resource_alignment_lock = SPIN_LOCK_UNLOCKED; | 2569 | spinlock_t resource_alignment_lock = SPIN_LOCK_UNLOCKED; |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 3b54b3940178..a0d9ee1df349 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -7,6 +7,8 @@ menu "Graphics support" | |||
7 | 7 | ||
8 | source "drivers/char/agp/Kconfig" | 8 | source "drivers/char/agp/Kconfig" |
9 | 9 | ||
10 | source "drivers/gpu/vga/Kconfig" | ||
11 | |||
10 | source "drivers/gpu/drm/Kconfig" | 12 | source "drivers/gpu/drm/Kconfig" |
11 | 13 | ||
12 | config VGASTATE | 14 | config VGASTATE |
diff --git a/include/linux/pci.h b/include/linux/pci.h index a90f94020798..6dbb1fd30e5a 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -806,6 +806,8 @@ int pci_cfg_space_size_ext(struct pci_dev *dev); | |||
806 | int pci_cfg_space_size(struct pci_dev *dev); | 806 | int pci_cfg_space_size(struct pci_dev *dev); |
807 | unsigned char pci_bus_max_busnr(struct pci_bus *bus); | 807 | unsigned char pci_bus_max_busnr(struct pci_bus *bus); |
808 | 808 | ||
809 | int pci_set_vga_state(struct pci_dev *pdev, bool decode, | ||
810 | unsigned int command_bits, bool change_bridge); | ||
809 | /* kmem_cache style wrapper around pci_alloc_consistent() */ | 811 | /* kmem_cache style wrapper around pci_alloc_consistent() */ |
810 | 812 | ||
811 | #include <linux/dmapool.h> | 813 | #include <linux/dmapool.h> |
diff --git a/include/linux/vgaarb.h b/include/linux/vgaarb.h new file mode 100644 index 000000000000..68229ce80fde --- /dev/null +++ b/include/linux/vgaarb.h | |||
@@ -0,0 +1,195 @@ | |||
1 | /* | ||
2 | * vgaarb.c | ||
3 | * | ||
4 | * (C) Copyright 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org> | ||
5 | * (C) Copyright 2007 Paulo R. Zanoni <przanoni@gmail.com> | ||
6 | * (C) Copyright 2007, 2009 Tiago Vignatti <vignatti@freedesktop.org> | ||
7 | */ | ||
8 | |||
9 | #ifndef LINUX_VGA_H | ||
10 | |||
11 | #include <asm/vga.h> | ||
12 | |||
13 | /* Legacy VGA regions */ | ||
14 | #define VGA_RSRC_NONE 0x00 | ||
15 | #define VGA_RSRC_LEGACY_IO 0x01 | ||
16 | #define VGA_RSRC_LEGACY_MEM 0x02 | ||
17 | #define VGA_RSRC_LEGACY_MASK (VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM) | ||
18 | /* Non-legacy access */ | ||
19 | #define VGA_RSRC_NORMAL_IO 0x04 | ||
20 | #define VGA_RSRC_NORMAL_MEM 0x08 | ||
21 | |||
22 | /* Passing that instead of a pci_dev to use the system "default" | ||
23 | * device, that is the one used by vgacon. Archs will probably | ||
24 | * have to provide their own vga_default_device(); | ||
25 | */ | ||
26 | #define VGA_DEFAULT_DEVICE (NULL) | ||
27 | |||
28 | /* For use by clients */ | ||
29 | |||
30 | /** | ||
31 | * vga_set_legacy_decoding | ||
32 | * | ||
33 | * @pdev: pci device of the VGA card | ||
34 | * @decodes: bit mask of what legacy regions the card decodes | ||
35 | * | ||
36 | * Indicates to the arbiter if the card decodes legacy VGA IOs, | ||
37 | * legacy VGA Memory, both, or none. All cards default to both, | ||
38 | * the card driver (fbdev for example) should tell the arbiter | ||
39 | * if it has disabled legacy decoding, so the card can be left | ||
40 | * out of the arbitration process (and can be safe to take | ||
41 | * interrupts at any time. | ||
42 | */ | ||
43 | extern void vga_set_legacy_decoding(struct pci_dev *pdev, | ||
44 | unsigned int decodes); | ||
45 | |||
46 | /** | ||
47 | * vga_get - acquire & locks VGA resources | ||
48 | * | ||
49 | * pdev: pci device of the VGA card or NULL for the system default | ||
50 | * rsrc: bit mask of resources to acquire and lock | ||
51 | * interruptible: blocking should be interruptible by signals ? | ||
52 | * | ||
53 | * This function acquires VGA resources for the given | ||
54 | * card and mark those resources locked. If the resource requested | ||
55 | * are "normal" (and not legacy) resources, the arbiter will first check | ||
56 | * wether the card is doing legacy decoding for that type of resource. If | ||
57 | * yes, the lock is "converted" into a legacy resource lock. | ||
58 | * The arbiter will first look for all VGA cards that might conflict | ||
59 | * and disable their IOs and/or Memory access, inlcuding VGA forwarding | ||
60 | * on P2P bridges if necessary, so that the requested resources can | ||
61 | * be used. Then, the card is marked as locking these resources and | ||
62 | * the IO and/or Memory accesse are enabled on the card (including | ||
63 | * VGA forwarding on parent P2P bridges if any). | ||
64 | * This function will block if some conflicting card is already locking | ||
65 | * one of the required resources (or any resource on a different bus | ||
66 | * segment, since P2P bridges don't differenciate VGA memory and IO | ||
67 | * afaik). You can indicate wether this blocking should be interruptible | ||
68 | * by a signal (for userland interface) or not. | ||
69 | * Must not be called at interrupt time or in atomic context. | ||
70 | * If the card already owns the resources, the function succeeds. | ||
71 | * Nested calls are supported (a per-resource counter is maintained) | ||
72 | */ | ||
73 | |||
74 | extern int vga_get(struct pci_dev *pdev, unsigned int rsrc, | ||
75 | int interruptible); | ||
76 | |||
77 | /** | ||
78 | * vga_get_interruptible | ||
79 | * | ||
80 | * Shortcut to vga_get | ||
81 | */ | ||
82 | |||
83 | static inline int vga_get_interruptible(struct pci_dev *pdev, | ||
84 | unsigned int rsrc) | ||
85 | { | ||
86 | return vga_get(pdev, rsrc, 1); | ||
87 | } | ||
88 | |||
89 | /** | ||
90 | * vga_get_interruptible | ||
91 | * | ||
92 | * Shortcut to vga_get | ||
93 | */ | ||
94 | |||
95 | static inline int vga_get_uninterruptible(struct pci_dev *pdev, | ||
96 | unsigned int rsrc) | ||
97 | { | ||
98 | return vga_get(pdev, rsrc, 0); | ||
99 | } | ||
100 | |||
101 | /** | ||
102 | * vga_tryget - try to acquire & lock legacy VGA resources | ||
103 | * | ||
104 | * @pdev: pci devivce of VGA card or NULL for system default | ||
105 | * @rsrc: bit mask of resources to acquire and lock | ||
106 | * | ||
107 | * This function performs the same operation as vga_get(), but | ||
108 | * will return an error (-EBUSY) instead of blocking if the resources | ||
109 | * are already locked by another card. It can be called in any context | ||
110 | */ | ||
111 | |||
112 | extern int vga_tryget(struct pci_dev *pdev, unsigned int rsrc); | ||
113 | |||
114 | /** | ||
115 | * vga_put - release lock on legacy VGA resources | ||
116 | * | ||
117 | * @pdev: pci device of VGA card or NULL for system default | ||
118 | * @rsrc: but mask of resource to release | ||
119 | * | ||
120 | * This function releases resources previously locked by vga_get() | ||
121 | * or vga_tryget(). The resources aren't disabled right away, so | ||
122 | * that a subsequence vga_get() on the same card will succeed | ||
123 | * immediately. Resources have a counter, so locks are only | ||
124 | * released if the counter reaches 0. | ||
125 | */ | ||
126 | |||
127 | extern void vga_put(struct pci_dev *pdev, unsigned int rsrc); | ||
128 | |||
129 | |||
130 | /** | ||
131 | * vga_default_device | ||
132 | * | ||
133 | * This can be defined by the platform. The default implementation | ||
134 | * is rather dumb and will probably only work properly on single | ||
135 | * vga card setups and/or x86 platforms. | ||
136 | * | ||
137 | * If your VGA default device is not PCI, you'll have to return | ||
138 | * NULL here. In this case, I assume it will not conflict with | ||
139 | * any PCI card. If this is not true, I'll have to define two archs | ||
140 | * hooks for enabling/disabling the VGA default device if that is | ||
141 | * possible. This may be a problem with real _ISA_ VGA cards, in | ||
142 | * addition to a PCI one. I don't know at this point how to deal | ||
143 | * with that card. Can theirs IOs be disabled at all ? If not, then | ||
144 | * I suppose it's a matter of having the proper arch hook telling | ||
145 | * us about it, so we basically never allow anybody to succeed a | ||
146 | * vga_get()... | ||
147 | */ | ||
148 | |||
149 | #ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE | ||
150 | extern struct pci_dev *vga_default_device(void); | ||
151 | #endif | ||
152 | |||
153 | /** | ||
154 | * vga_conflicts | ||
155 | * | ||
156 | * Architectures should define this if they have several | ||
157 | * independant PCI domains that can afford concurrent VGA | ||
158 | * decoding | ||
159 | */ | ||
160 | |||
161 | #ifndef __ARCH_HAS_VGA_CONFLICT | ||
162 | static inline int vga_conflicts(struct pci_dev *p1, struct pci_dev *p2) | ||
163 | { | ||
164 | return 1; | ||
165 | } | ||
166 | #endif | ||
167 | |||
168 | /* | ||
169 | * Register a client with the VGA arbitration logic | ||
170 | * return value: number of VGA devices in system. | ||
171 | * | ||
172 | * Clients have two callback mechanisms they can use. | ||
173 | * irq enable/disable callback - | ||
174 | * If a client can't disable its GPUs VGA resources, then we | ||
175 | * need to be able to ask it to turn off its irqs when we | ||
176 | * turn off its mem and io decoding. | ||
177 | * set_vga_decode | ||
178 | * If a client can disable its GPU VGA resource, it will | ||
179 | * get a callback from this to set the encode/decode state | ||
180 | * | ||
181 | * Clients with disable abilities should check the return value | ||
182 | * of this function and if the VGA device count is > 1, should | ||
183 | * disable VGA decoding resources. | ||
184 | * | ||
185 | * Rationale: we cannot disable VGA decode resources unconditionally | ||
186 | * some single GPU laptops seem to require ACPI or BIOS access to the | ||
187 | * VGA registers to control things like backlights etc. | ||
188 | * Hopefully newer multi-GPU laptops do something saner, and desktops | ||
189 | * won't have any special ACPI for this. | ||
190 | */ | ||
191 | int vga_client_register(struct pci_dev *pdev, void *cookie, | ||
192 | void (*irq_set_state)(void *cookie, bool state), | ||
193 | unsigned int (*set_vga_decode)(void *cookie, bool state)); | ||
194 | |||
195 | #endif /* LINUX_VGA_H */ | ||