Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[SPARC64]: Fix PCI memory space root resource on Hummingbird.

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>

+29 -23
+10 -19
arch/sparc64/kernel/pci_common.c
··· 330 330 return res; 331 331 } 332 332 333 - static int __init pdev_resource_collisions_expected(struct pci_dev *pdev) 334 - { 335 - if (pdev->vendor != PCI_VENDOR_ID_SUN) 336 - return 0; 337 - 338 - if (pdev->device == PCI_DEVICE_ID_SUN_RIO_EBUS || 339 - pdev->device == PCI_DEVICE_ID_SUN_RIO_1394 || 340 - pdev->device == PCI_DEVICE_ID_SUN_RIO_USB) 341 - return 1; 342 - 343 - return 0; 344 - } 345 - 346 333 static void __init pdev_record_assignments(struct pci_pbm_info *pbm, 347 334 struct pci_dev *pdev) 348 335 { ··· 387 400 pbm->parent->resource_adjust(pdev, res, root); 388 401 389 402 if (request_resource(root, res) < 0) { 403 + int rnum; 404 + 390 405 /* OK, there is some conflict. But this is fine 391 406 * since we'll reassign it in the fixup pass. 392 407 * 393 - * We notify the user that OBP made an error if it 394 - * is a case we don't expect. 408 + * Do not print the warning for ROM resources 409 + * as such a conflict is quite common and 410 + * harmless as the ROM bar is disabled. 395 411 */ 396 - if (!pdev_resource_collisions_expected(pdev)) { 397 - printk(KERN_ERR "PCI: Address space collision on region %ld " 412 + rnum = (res - &pdev->resource[0]); 413 + if (rnum != PCI_ROM_RESOURCE) 414 + printk(KERN_ERR "PCI: Resource collision, " 415 + "region %d " 398 416 "[%016lx:%016lx] of device %s\n", 399 - (res - &pdev->resource[0]), 417 + rnum, 400 418 res->start, res->end, 401 419 pci_name(pdev)); 402 - } 403 420 } 404 421 } 405 422 }
+19 -4
arch/sparc64/kernel/pci_sabre.c
··· 1196 1196 &pbm->mem_space); 1197 1197 } 1198 1198 1199 - static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 dma_begin) 1199 + static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 dma_start, u32 dma_end) 1200 1200 { 1201 1201 struct pci_pbm_info *pbm; 1202 1202 struct device_node *node; ··· 1261 1261 node = node->sibling; 1262 1262 } 1263 1263 if (simbas_found == 0) { 1264 + struct resource *rp; 1265 + 1264 1266 /* No APBs underneath, probably this is a hummingbird 1265 1267 * system. 1266 1268 */ ··· 1304 1302 pbm->io_space.end = pbm->io_space.start + (1UL << 24) - 1UL; 1305 1303 pbm->io_space.flags = IORESOURCE_IO; 1306 1304 1307 - pbm->mem_space.start = p->pbm_A.controller_regs + SABRE_MEMSPACE; 1308 - pbm->mem_space.end = pbm->mem_space.start + (unsigned long)dma_begin - 1UL; 1305 + pbm->mem_space.start = 1306 + (p->pbm_A.controller_regs + SABRE_MEMSPACE); 1307 + pbm->mem_space.end = 1308 + (pbm->mem_space.start + ((1UL << 32UL) - 1UL)); 1309 1309 pbm->mem_space.flags = IORESOURCE_MEM; 1310 1310 1311 1311 if (request_resource(&ioport_resource, &pbm->io_space) < 0) { ··· 1318 1314 prom_printf("Cannot register Hummingbird's MEM space.\n"); 1319 1315 prom_halt(); 1320 1316 } 1317 + 1318 + rp = kmalloc(sizeof(*rp), GFP_KERNEL); 1319 + if (!rp) { 1320 + prom_printf("Cannot allocate IOMMU resource.\n"); 1321 + prom_halt(); 1322 + } 1323 + rp->name = "IOMMU"; 1324 + rp->start = pbm->mem_space.start + (unsigned long) dma_start; 1325 + rp->end = pbm->mem_space.start + (unsigned long) dma_end - 1UL; 1326 + rp->flags = IORESOURCE_BUSY; 1327 + request_resource(&pbm->mem_space, rp); 1321 1328 1322 1329 pci_register_legacy_regions(&pbm->io_space, 1323 1330 &pbm->mem_space); ··· 1465 1450 /* 1466 1451 * Look for APB underneath. 1467 1452 */ 1468 - sabre_pbm_init(p, dp, vdma[0]); 1453 + sabre_pbm_init(p, dp, vdma[0], vdma[1]); 1469 1454 }