Skip to content

Commit

Permalink
[SPARC64]: Fix PCI memory space root resource on Hummingbird.
Browse files Browse the repository at this point in the history
For Hummingbird PCI controllers, we should create the root
PCI memory space resource as the full 4GB area, and then
allocate the IOMMU DMA translation window out of there.

The old code just assumed that the IOMMU DMA translation base
to the top of the 4GB area was unusable.  This is not true on
many systems such as SB100 and SB150, where the IOMMU DMA
translation window sits at 0xc0000000->0xdfffffff.

So what would happen is that any device mapped by the firmware
at the top section 0xe0000000->0xffffffff would get remapped
by Linux somewhere else leading to all kinds of problems and
boot failures.

While we're here, report more cases of OBP resource assignment
conflicts.  The only truly valid ones are ROM resource conflicts.

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Oct 18, 2006
1 parent 7341df1 commit 5aee87c
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 23 deletions.
29 changes: 10 additions & 19 deletions arch/sparc64/kernel/pci_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -330,19 +330,6 @@ __init get_device_resource(struct linux_prom_pci_registers *ap,
return res;
}

static int __init pdev_resource_collisions_expected(struct pci_dev *pdev)
{
if (pdev->vendor != PCI_VENDOR_ID_SUN)
return 0;

if (pdev->device == PCI_DEVICE_ID_SUN_RIO_EBUS ||
pdev->device == PCI_DEVICE_ID_SUN_RIO_1394 ||
pdev->device == PCI_DEVICE_ID_SUN_RIO_USB)
return 1;

return 0;
}

static void __init pdev_record_assignments(struct pci_pbm_info *pbm,
struct pci_dev *pdev)
{
Expand Down Expand Up @@ -400,19 +387,23 @@ static void __init pdev_record_assignments(struct pci_pbm_info *pbm,
pbm->parent->resource_adjust(pdev, res, root);

if (request_resource(root, res) < 0) {
int rnum;

/* OK, there is some conflict. But this is fine
* since we'll reassign it in the fixup pass.
*
* We notify the user that OBP made an error if it
* is a case we don't expect.
* Do not print the warning for ROM resources
* as such a conflict is quite common and
* harmless as the ROM bar is disabled.
*/
if (!pdev_resource_collisions_expected(pdev)) {
printk(KERN_ERR "PCI: Address space collision on region %ld "
rnum = (res - &pdev->resource[0]);
if (rnum != PCI_ROM_RESOURCE)
printk(KERN_ERR "PCI: Resource collision, "
"region %d "
"[%016lx:%016lx] of device %s\n",
(res - &pdev->resource[0]),
rnum,
res->start, res->end,
pci_name(pdev));
}
}
}
}
Expand Down
23 changes: 19 additions & 4 deletions arch/sparc64/kernel/pci_sabre.c
Original file line number Diff line number Diff line change
Expand Up @@ -1196,7 +1196,7 @@ static void pbm_register_toplevel_resources(struct pci_controller_info *p,
&pbm->mem_space);
}

static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 dma_begin)
static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 dma_start, u32 dma_end)
{
struct pci_pbm_info *pbm;
struct device_node *node;
Expand Down Expand Up @@ -1261,6 +1261,8 @@ static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp
node = node->sibling;
}
if (simbas_found == 0) {
struct resource *rp;

/* No APBs underneath, probably this is a hummingbird
* system.
*/
Expand Down Expand Up @@ -1302,8 +1304,10 @@ static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp
pbm->io_space.end = pbm->io_space.start + (1UL << 24) - 1UL;
pbm->io_space.flags = IORESOURCE_IO;

pbm->mem_space.start = p->pbm_A.controller_regs + SABRE_MEMSPACE;
pbm->mem_space.end = pbm->mem_space.start + (unsigned long)dma_begin - 1UL;
pbm->mem_space.start =
(p->pbm_A.controller_regs + SABRE_MEMSPACE);
pbm->mem_space.end =
(pbm->mem_space.start + ((1UL << 32UL) - 1UL));
pbm->mem_space.flags = IORESOURCE_MEM;

if (request_resource(&ioport_resource, &pbm->io_space) < 0) {
Expand All @@ -1315,6 +1319,17 @@ static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp
prom_halt();
}

rp = kmalloc(sizeof(*rp), GFP_KERNEL);
if (!rp) {
prom_printf("Cannot allocate IOMMU resource.\n");
prom_halt();
}
rp->name = "IOMMU";
rp->start = pbm->mem_space.start + (unsigned long) dma_start;
rp->end = pbm->mem_space.start + (unsigned long) dma_end - 1UL;
rp->flags = IORESOURCE_BUSY;
request_resource(&pbm->mem_space, rp);

pci_register_legacy_regions(&pbm->io_space,
&pbm->mem_space);
}
Expand Down Expand Up @@ -1450,5 +1465,5 @@ void sabre_init(struct device_node *dp, char *model_name)
/*
* Look for APB underneath.
*/
sabre_pbm_init(p, dp, vdma[0]);
sabre_pbm_init(p, dp, vdma[0], vdma[1]);
}

0 comments on commit 5aee87c

Please sign in to comment.