aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-02-14 19:42:11 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-03-20 04:12:57 -0500
commit987b6de7102cf2f583733efd726ae920a1335519 (patch)
tree66a0fcfa5be6831c47f008437d3c97d0bead91bb
parent9f8a5b843fc47ea150525f912574677483e1a5ac (diff)
[SPARC64]: Restrict PCI bus scanning on SUN4V.
On the PBM's first bus number, only allow device 0, function 0, to be poked at with PCI config space accesses. For some reason, this single device responds to all device numbers. Also, reduce the verbiage of the debugging log printk's for PCI cfg space accesses in the SUN4V PCI controller driver, so that it doesn't overwhelm the slow SUN4V hypervisor console. Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--arch/sparc64/kernel/pci_sun4v.c36
1 files changed, 16 insertions, 20 deletions
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index ac311d3dbc5c..ea51ade43b8b 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -517,8 +517,14 @@ struct pci_iommu_ops pci_sun4v_iommu_ops = {
517 517
518/* SUN4V PCI configuration space accessors. */ 518/* SUN4V PCI configuration space accessors. */
519 519
520static inline int pci_sun4v_out_of_range(struct pci_pbm_info *pbm, unsigned int bus) 520static inline int pci_sun4v_out_of_range(struct pci_pbm_info *pbm, unsigned int bus, unsigned int device, unsigned int func)
521{ 521{
522 if (bus == pbm->pci_first_busno) {
523 if (device == 0 && func == 0)
524 return 0;
525 return 1;
526 }
527
522 if (bus < pbm->pci_first_busno || 528 if (bus < pbm->pci_first_busno ||
523 bus > pbm->pci_last_busno) 529 bus > pbm->pci_last_busno)
524 return 1; 530 return 1;
@@ -535,15 +541,14 @@ static int pci_sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
535 unsigned int func = PCI_FUNC(devfn); 541 unsigned int func = PCI_FUNC(devfn);
536 unsigned long ret; 542 unsigned long ret;
537 543
538 if (pci_sun4v_out_of_range(pbm, bus)) { 544 if (pci_sun4v_out_of_range(pbm, bus, device, func)) {
539 ret = ~0UL; 545 ret = ~0UL;
540 } else { 546 } else {
541 ret = pci_sun4v_config_get(devhandle, 547 ret = pci_sun4v_config_get(devhandle,
542 HV_PCI_DEVICE_BUILD(bus, device, func), 548 HV_PCI_DEVICE_BUILD(bus, device, func),
543 where, size); 549 where, size);
544#if 0 550#if 0
545 printk("read_pci_cfg: devh[%x] device[%08x] where[%x] sz[%d] " 551 printk("rcfg: [%x:%x:%x:%d]=[%lx]\n",
546 "== [%016lx]\n",
547 devhandle, HV_PCI_DEVICE_BUILD(bus, device, func), 552 devhandle, HV_PCI_DEVICE_BUILD(bus, device, func),
548 where, size, ret); 553 where, size, ret);
549#endif 554#endif
@@ -574,15 +579,14 @@ static int pci_sun4v_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
574 unsigned int func = PCI_FUNC(devfn); 579 unsigned int func = PCI_FUNC(devfn);
575 unsigned long ret; 580 unsigned long ret;
576 581
577 if (pci_sun4v_out_of_range(pbm, bus)) { 582 if (pci_sun4v_out_of_range(pbm, bus, device, func)) {
578 /* Do nothing. */ 583 /* Do nothing. */
579 } else { 584 } else {
580 ret = pci_sun4v_config_put(devhandle, 585 ret = pci_sun4v_config_put(devhandle,
581 HV_PCI_DEVICE_BUILD(bus, device, func), 586 HV_PCI_DEVICE_BUILD(bus, device, func),
582 where, size, value); 587 where, size, value);
583#if 0 588#if 0
584 printk("write_pci_cfg: devh[%x] device[%08x] where[%x] sz[%d] " 589 printk("wcfg: [%x:%x:%x:%d] v[%x] == [%lx]\n",
585 "val[%08x] == [%016lx]\n",
586 devhandle, HV_PCI_DEVICE_BUILD(bus, device, func), 590 devhandle, HV_PCI_DEVICE_BUILD(bus, device, func),
587 where, size, value, ret); 591 where, size, value, ret);
588#endif 592#endif
@@ -610,16 +614,13 @@ static void pbm_scan_bus(struct pci_controller_info *p,
610 memset(cookie, 0, sizeof(*cookie)); 614 memset(cookie, 0, sizeof(*cookie));
611 cookie->pbm = pbm; 615 cookie->pbm = pbm;
612 616
613 pbm->pci_bus = pci_scan_bus(pbm->pci_first_busno, 617 pbm->pci_bus = pci_scan_bus(pbm->pci_first_busno, p->pci_ops, pbm);
614 p->pci_ops,
615 pbm);
616#if 0 618#if 0
617 pci_fixup_host_bridge_self(pbm->pci_bus); 619 pci_fixup_host_bridge_self(pbm->pci_bus);
618 pbm->pci_bus->self->sysdata = cookie; 620 pbm->pci_bus->self->sysdata = cookie;
619#endif 621#endif
620
621 pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, 622 pci_fill_in_pbm_cookies(pbm->pci_bus, pbm,
622 prom_getchild(pbm->prom_node)); 623 pbm->prom_node);
623 pci_record_assignments(pbm, pbm->pci_bus); 624 pci_record_assignments(pbm, pbm->pci_bus);
624 pci_assign_unassigned(pbm, pbm->pci_bus); 625 pci_assign_unassigned(pbm, pbm->pci_bus);
625 pci_fixup_irq(pbm, pbm->pci_bus); 626 pci_fixup_irq(pbm, pbm->pci_bus);
@@ -884,19 +885,12 @@ static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm)
884 probe_existing_entries(pbm, iommu); 885 probe_existing_entries(pbm, iommu);
885} 886}
886 887
887/* Don't get this from the root nexus, get it from the "pci@0" node below. */
888static void pci_sun4v_get_bus_range(struct pci_pbm_info *pbm) 888static void pci_sun4v_get_bus_range(struct pci_pbm_info *pbm)
889{ 889{
890 unsigned int busrange[2]; 890 unsigned int busrange[2];
891 int prom_node = pbm->prom_node; 891 int prom_node = pbm->prom_node;
892 int err; 892 int err;
893 893
894 prom_node = prom_getchild(prom_node);
895 if (prom_node == 0) {
896 prom_printf("%s: Fatal error, no child OBP node.\n", pbm->name);
897 prom_halt();
898 }
899
900 err = prom_getproperty(prom_node, "bus-range", 894 err = prom_getproperty(prom_node, "bus-range",
901 (char *)&busrange[0], 895 (char *)&busrange[0],
902 sizeof(busrange)); 896 sizeof(busrange));
@@ -929,7 +923,9 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, int prom_node, u32
929 sprintf(pbm->name, "SUN4V-PCI%d PBM%c", 923 sprintf(pbm->name, "SUN4V-PCI%d PBM%c",
930 p->index, (pbm == &p->pbm_A ? 'A' : 'B')); 924 p->index, (pbm == &p->pbm_A ? 'A' : 'B'));
931 925
932 printk("%s: devhandle[%x]\n", pbm->name, pbm->devhandle); 926 printk("%s: devhandle[%x] prom_node[%x:%x]\n",
927 pbm->name, pbm->devhandle,
928 pbm->prom_node, prom_getchild(pbm->prom_node));
933 929
934 prom_getstring(prom_node, "name", 930 prom_getstring(prom_node, "name",
935 pbm->prom_name, sizeof(pbm->prom_name)); 931 pbm->prom_name, sizeof(pbm->prom_name));