@@ -61,7 +61,7 @@ struct vga_device {
61
61
unsigned int mem_lock_cnt ; /* legacy MEM lock count */
62
62
unsigned int io_norm_cnt ; /* normal IO count */
63
63
unsigned int mem_norm_cnt ; /* normal MEM count */
64
-
64
+ bool bridge_has_one_vga ;
65
65
/* allow IRQ enable/disable hook */
66
66
void * cookie ;
67
67
void (* irq_set_state )(void * cookie , bool enable );
@@ -165,6 +165,8 @@ static struct vga_device *__vga_tryget(struct vga_device *vgadev,
165
165
unsigned int wants , legacy_wants , match ;
166
166
struct vga_device * conflict ;
167
167
unsigned int pci_bits ;
168
+ u32 flags = 0 ;
169
+
168
170
/* Account for "normal" resources to lock. If we decode the legacy,
169
171
* counterpart, we need to request it as well
170
172
*/
@@ -237,16 +239,23 @@ static struct vga_device *__vga_tryget(struct vga_device *vgadev,
237
239
/* looks like he doesn't have a lock, we can steal
238
240
* them from him
239
241
*/
240
- vga_irq_set_state (conflict , false);
241
242
243
+ flags = 0 ;
242
244
pci_bits = 0 ;
243
- if (lwants & (VGA_RSRC_LEGACY_MEM |VGA_RSRC_NORMAL_MEM ))
244
- pci_bits |= PCI_COMMAND_MEMORY ;
245
- if (lwants & (VGA_RSRC_LEGACY_IO |VGA_RSRC_NORMAL_IO ))
246
- pci_bits |= PCI_COMMAND_IO ;
247
245
248
- pci_set_vga_state (conflict -> pdev , false, pci_bits ,
249
- change_bridge );
246
+ if (!conflict -> bridge_has_one_vga ) {
247
+ vga_irq_set_state (conflict , false);
248
+ flags |= PCI_VGA_STATE_CHANGE_DECODES ;
249
+ if (lwants & (VGA_RSRC_LEGACY_MEM |VGA_RSRC_NORMAL_MEM ))
250
+ pci_bits |= PCI_COMMAND_MEMORY ;
251
+ if (lwants & (VGA_RSRC_LEGACY_IO |VGA_RSRC_NORMAL_IO ))
252
+ pci_bits |= PCI_COMMAND_IO ;
253
+ }
254
+
255
+ if (change_bridge )
256
+ flags |= PCI_VGA_STATE_CHANGE_BRIDGE ;
257
+
258
+ pci_set_vga_state (conflict -> pdev , false, pci_bits , flags );
250
259
conflict -> owns &= ~lwants ;
251
260
/* If he also owned non-legacy, that is no longer the case */
252
261
if (lwants & VGA_RSRC_LEGACY_MEM )
@@ -261,14 +270,24 @@ static struct vga_device *__vga_tryget(struct vga_device *vgadev,
261
270
* also have in "decodes". We can lock resources we don't decode but
262
271
* not own them.
263
272
*/
273
+ flags = 0 ;
264
274
pci_bits = 0 ;
265
- if (wants & (VGA_RSRC_LEGACY_MEM |VGA_RSRC_NORMAL_MEM ))
266
- pci_bits |= PCI_COMMAND_MEMORY ;
267
- if (wants & (VGA_RSRC_LEGACY_IO |VGA_RSRC_NORMAL_IO ))
268
- pci_bits |= PCI_COMMAND_IO ;
269
- pci_set_vga_state (vgadev -> pdev , true, pci_bits , !!(wants & VGA_RSRC_LEGACY_MASK ));
270
275
271
- vga_irq_set_state (vgadev , true);
276
+ if (!vgadev -> bridge_has_one_vga ) {
277
+ flags |= PCI_VGA_STATE_CHANGE_DECODES ;
278
+ if (wants & (VGA_RSRC_LEGACY_MEM |VGA_RSRC_NORMAL_MEM ))
279
+ pci_bits |= PCI_COMMAND_MEMORY ;
280
+ if (wants & (VGA_RSRC_LEGACY_IO |VGA_RSRC_NORMAL_IO ))
281
+ pci_bits |= PCI_COMMAND_IO ;
282
+ }
283
+ if (!!(wants & VGA_RSRC_LEGACY_MASK ))
284
+ flags |= PCI_VGA_STATE_CHANGE_BRIDGE ;
285
+
286
+ pci_set_vga_state (vgadev -> pdev , true, pci_bits , flags );
287
+
288
+ if (!vgadev -> bridge_has_one_vga ) {
289
+ vga_irq_set_state (vgadev , true);
290
+ }
272
291
vgadev -> owns |= (wants & vgadev -> decodes );
273
292
lock_them :
274
293
vgadev -> locks |= (rsrc & VGA_RSRC_LEGACY_MASK );
@@ -421,6 +440,62 @@ void vga_put(struct pci_dev *pdev, unsigned int rsrc)
421
440
}
422
441
EXPORT_SYMBOL (vga_put );
423
442
443
+ /* Rules for using a bridge to control a VGA descendant decoding:
444
+ if a bridge has only one VGA descendant then it can be used
445
+ to control the VGA routing for that device.
446
+ It should always use the bridge closest to the device to control it.
447
+ If a bridge has a direct VGA descendant, but also have a sub-bridge
448
+ VGA descendant then we cannot use that bridge to control the direct VGA descendant.
449
+ So for every device we register, we need to iterate all its parent bridges
450
+ so we can invalidate any devices using them properly.
451
+ */
452
+ static void vga_arbiter_check_bridge_sharing (struct vga_device * vgadev )
453
+ {
454
+ struct vga_device * same_bridge_vgadev ;
455
+ struct pci_bus * new_bus , * bus ;
456
+ struct pci_dev * new_bridge , * bridge ;
457
+
458
+ vgadev -> bridge_has_one_vga = true;
459
+
460
+ if (list_empty (& vga_list ))
461
+ return ;
462
+
463
+ /* okay iterate the new devices bridge hierarachy */
464
+ new_bus = vgadev -> pdev -> bus ;
465
+ while (new_bus ) {
466
+ new_bridge = new_bus -> self ;
467
+
468
+ if (new_bridge ) {
469
+ /* go through list of devices already registered */
470
+ list_for_each_entry (same_bridge_vgadev , & vga_list , list ) {
471
+ bus = same_bridge_vgadev -> pdev -> bus ;
472
+ bridge = bus -> self ;
473
+
474
+ /* see if the share a bridge with this device */
475
+ if (new_bridge == bridge ) {
476
+ /* if their direct parent bridge is the same
477
+ as any bridge of this device then it can't be used
478
+ for that device */
479
+ same_bridge_vgadev -> bridge_has_one_vga = false;
480
+ }
481
+
482
+ /* now iterate the previous devices bridge hierarchy */
483
+ /* if the new devices parent bridge is in the other devices
484
+ hierarchy then we can't use it to control this device */
485
+ while (bus ) {
486
+ bridge = bus -> self ;
487
+ if (bridge ) {
488
+ if (bridge == vgadev -> pdev -> bus -> self )
489
+ vgadev -> bridge_has_one_vga = false;
490
+ }
491
+ bus = bus -> parent ;
492
+ }
493
+ }
494
+ }
495
+ new_bus = new_bus -> parent ;
496
+ }
497
+ }
498
+
424
499
/*
425
500
* Currently, we assume that the "initial" setup of the system is
426
501
* not sane, that is we come up with conflicting devices and let
@@ -500,6 +575,8 @@ static bool vga_arbiter_add_pci_device(struct pci_dev *pdev)
500
575
vga_default = pci_dev_get (pdev );
501
576
#endif
502
577
578
+ vga_arbiter_check_bridge_sharing (vgadev );
579
+
503
580
/* Add to the list */
504
581
list_add (& vgadev -> list , & vga_list );
505
582
vga_count ++ ;
@@ -1222,6 +1299,7 @@ static int __init vga_arb_device_init(void)
1222
1299
{
1223
1300
int rc ;
1224
1301
struct pci_dev * pdev ;
1302
+ struct vga_device * vgadev ;
1225
1303
1226
1304
rc = misc_register (& vga_arb_device );
1227
1305
if (rc < 0 )
@@ -1238,6 +1316,13 @@ static int __init vga_arb_device_init(void)
1238
1316
vga_arbiter_add_pci_device (pdev );
1239
1317
1240
1318
pr_info ("vgaarb: loaded\n" );
1319
+
1320
+ list_for_each_entry (vgadev , & vga_list , list ) {
1321
+ if (vgadev -> bridge_has_one_vga )
1322
+ pr_info ("vgaarb: bridge control possible %s\n" , pci_name (vgadev -> pdev ));
1323
+ else
1324
+ pr_info ("vgaarb: no bridge control possible %s\n" , pci_name (vgadev -> pdev ));
1325
+ }
1241
1326
return rc ;
1242
1327
}
1243
1328
subsys_initcall (vga_arb_device_init );
0 commit comments