diff options
Diffstat (limited to 'arch/powerpc/kernel/pci_32.c')
-rw-r--r-- | arch/powerpc/kernel/pci_32.c | 510 |
1 files changed, 15 insertions, 495 deletions
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index e66064b5093a..0adf077f3f3a 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c | |||
@@ -55,8 +55,7 @@ static u8* pci_to_OF_bus_map; | |||
55 | */ | 55 | */ |
56 | int pci_assign_all_buses; | 56 | int pci_assign_all_buses; |
57 | 57 | ||
58 | struct pci_controller* hose_head; | 58 | LIST_HEAD(hose_list); |
59 | struct pci_controller** hose_tail = &hose_head; | ||
60 | 59 | ||
61 | static int pci_bus_count; | 60 | static int pci_bus_count; |
62 | 61 | ||
@@ -573,58 +572,6 @@ pcibios_assign_resources(void) | |||
573 | } | 572 | } |
574 | } | 573 | } |
575 | 574 | ||
576 | |||
577 | int | ||
578 | pcibios_enable_resources(struct pci_dev *dev, int mask) | ||
579 | { | ||
580 | u16 cmd, old_cmd; | ||
581 | int idx; | ||
582 | struct resource *r; | ||
583 | |||
584 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | ||
585 | old_cmd = cmd; | ||
586 | for (idx=0; idx<6; idx++) { | ||
587 | /* Only set up the requested stuff */ | ||
588 | if (!(mask & (1<<idx))) | ||
589 | continue; | ||
590 | |||
591 | r = &dev->resource[idx]; | ||
592 | if (r->flags & IORESOURCE_UNSET) { | ||
593 | printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", pci_name(dev)); | ||
594 | return -EINVAL; | ||
595 | } | ||
596 | if (r->flags & IORESOURCE_IO) | ||
597 | cmd |= PCI_COMMAND_IO; | ||
598 | if (r->flags & IORESOURCE_MEM) | ||
599 | cmd |= PCI_COMMAND_MEMORY; | ||
600 | } | ||
601 | if (dev->resource[PCI_ROM_RESOURCE].start) | ||
602 | cmd |= PCI_COMMAND_MEMORY; | ||
603 | if (cmd != old_cmd) { | ||
604 | printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd); | ||
605 | pci_write_config_word(dev, PCI_COMMAND, cmd); | ||
606 | } | ||
607 | return 0; | ||
608 | } | ||
609 | |||
610 | static int next_controller_index; | ||
611 | |||
612 | struct pci_controller * __init | ||
613 | pcibios_alloc_controller(void) | ||
614 | { | ||
615 | struct pci_controller *hose; | ||
616 | |||
617 | hose = (struct pci_controller *)alloc_bootmem(sizeof(*hose)); | ||
618 | memset(hose, 0, sizeof(struct pci_controller)); | ||
619 | |||
620 | *hose_tail = hose; | ||
621 | hose_tail = &hose->next; | ||
622 | |||
623 | hose->index = next_controller_index++; | ||
624 | |||
625 | return hose; | ||
626 | } | ||
627 | |||
628 | #ifdef CONFIG_PPC_OF | 575 | #ifdef CONFIG_PPC_OF |
629 | /* | 576 | /* |
630 | * Functions below are used on OpenFirmware machines. | 577 | * Functions below are used on OpenFirmware machines. |
@@ -670,7 +617,7 @@ void | |||
670 | pcibios_make_OF_bus_map(void) | 617 | pcibios_make_OF_bus_map(void) |
671 | { | 618 | { |
672 | int i; | 619 | int i; |
673 | struct pci_controller* hose; | 620 | struct pci_controller *hose, *tmp; |
674 | struct property *map_prop; | 621 | struct property *map_prop; |
675 | struct device_node *dn; | 622 | struct device_node *dn; |
676 | 623 | ||
@@ -687,7 +634,7 @@ pcibios_make_OF_bus_map(void) | |||
687 | pci_to_OF_bus_map[i] = 0xff; | 634 | pci_to_OF_bus_map[i] = 0xff; |
688 | 635 | ||
689 | /* For each hose, we begin searching bridges */ | 636 | /* For each hose, we begin searching bridges */ |
690 | for(hose=hose_head; hose; hose=hose->next) { | 637 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { |
691 | struct device_node* node; | 638 | struct device_node* node; |
692 | node = (struct device_node *)hose->arch_data; | 639 | node = (struct device_node *)hose->arch_data; |
693 | if (!node) | 640 | if (!node) |
@@ -765,7 +712,7 @@ static struct device_node *scan_OF_for_pci_bus(struct pci_bus *bus) | |||
765 | 712 | ||
766 | /* Are we a root bus ? */ | 713 | /* Are we a root bus ? */ |
767 | if (bus->self == NULL || bus->parent == NULL) { | 714 | if (bus->self == NULL || bus->parent == NULL) { |
768 | struct pci_controller *hose = pci_bus_to_hose(bus->number); | 715 | struct pci_controller *hose = pci_bus_to_host(bus); |
769 | if (hose == NULL) | 716 | if (hose == NULL) |
770 | return NULL; | 717 | return NULL; |
771 | return of_node_get(hose->arch_data); | 718 | return of_node_get(hose->arch_data); |
@@ -818,27 +765,6 @@ pci_device_to_OF_node(struct pci_dev *dev) | |||
818 | } | 765 | } |
819 | EXPORT_SYMBOL(pci_device_to_OF_node); | 766 | EXPORT_SYMBOL(pci_device_to_OF_node); |
820 | 767 | ||
821 | /* This routine is meant to be used early during boot, when the | ||
822 | * PCI bus numbers have not yet been assigned, and you need to | ||
823 | * issue PCI config cycles to an OF device. | ||
824 | * It could also be used to "fix" RTAS config cycles if you want | ||
825 | * to set pci_assign_all_buses to 1 and still use RTAS for PCI | ||
826 | * config cycles. | ||
827 | */ | ||
828 | struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node) | ||
829 | { | ||
830 | if (!have_of) | ||
831 | return NULL; | ||
832 | while(node) { | ||
833 | struct pci_controller* hose; | ||
834 | for (hose=hose_head;hose;hose=hose->next) | ||
835 | if (hose->arch_data == node) | ||
836 | return hose; | ||
837 | node=node->parent; | ||
838 | } | ||
839 | return NULL; | ||
840 | } | ||
841 | |||
842 | static int | 768 | static int |
843 | find_OF_pci_device_filter(struct device_node* node, void* data) | 769 | find_OF_pci_device_filter(struct device_node* node, void* data) |
844 | { | 770 | { |
@@ -1027,34 +953,12 @@ pci_create_OF_bus_map(void) | |||
1027 | } | 953 | } |
1028 | } | 954 | } |
1029 | 955 | ||
1030 | static ssize_t pci_show_devspec(struct device *dev, struct device_attribute *attr, char *buf) | ||
1031 | { | ||
1032 | struct pci_dev *pdev; | ||
1033 | struct device_node *np; | ||
1034 | |||
1035 | pdev = to_pci_dev (dev); | ||
1036 | np = pci_device_to_OF_node(pdev); | ||
1037 | if (np == NULL || np->full_name == NULL) | ||
1038 | return 0; | ||
1039 | return sprintf(buf, "%s", np->full_name); | ||
1040 | } | ||
1041 | static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL); | ||
1042 | |||
1043 | #else /* CONFIG_PPC_OF */ | 956 | #else /* CONFIG_PPC_OF */ |
1044 | void pcibios_make_OF_bus_map(void) | 957 | void pcibios_make_OF_bus_map(void) |
1045 | { | 958 | { |
1046 | } | 959 | } |
1047 | #endif /* CONFIG_PPC_OF */ | 960 | #endif /* CONFIG_PPC_OF */ |
1048 | 961 | ||
1049 | /* Add sysfs properties */ | ||
1050 | void pcibios_add_platform_entries(struct pci_dev *pdev) | ||
1051 | { | ||
1052 | #ifdef CONFIG_PPC_OF | ||
1053 | device_create_file(&pdev->dev, &dev_attr_devspec); | ||
1054 | #endif /* CONFIG_PPC_OF */ | ||
1055 | } | ||
1056 | |||
1057 | |||
1058 | #ifdef CONFIG_PPC_PMAC | 962 | #ifdef CONFIG_PPC_PMAC |
1059 | /* | 963 | /* |
1060 | * This set of routines checks for PCI<->PCI bridges that have closed | 964 | * This set of routines checks for PCI<->PCI bridges that have closed |
@@ -1269,14 +1173,14 @@ pcibios_fixup_p2p_bridges(void) | |||
1269 | static int __init | 1173 | static int __init |
1270 | pcibios_init(void) | 1174 | pcibios_init(void) |
1271 | { | 1175 | { |
1272 | struct pci_controller *hose; | 1176 | struct pci_controller *hose, *tmp; |
1273 | struct pci_bus *bus; | 1177 | struct pci_bus *bus; |
1274 | int next_busno; | 1178 | int next_busno = 0; |
1275 | 1179 | ||
1276 | printk(KERN_INFO "PCI: Probing PCI hardware\n"); | 1180 | printk(KERN_INFO "PCI: Probing PCI hardware\n"); |
1277 | 1181 | ||
1278 | /* Scan all of the recorded PCI controllers. */ | 1182 | /* Scan all of the recorded PCI controllers. */ |
1279 | for (next_busno = 0, hose = hose_head; hose; hose = hose->next) { | 1183 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { |
1280 | if (pci_assign_all_buses) | 1184 | if (pci_assign_all_buses) |
1281 | hose->first_busno = next_busno; | 1185 | hose->first_busno = next_busno; |
1282 | hose->last_busno = 0xff; | 1186 | hose->last_busno = 0xff; |
@@ -1319,12 +1223,6 @@ pcibios_init(void) | |||
1319 | 1223 | ||
1320 | subsys_initcall(pcibios_init); | 1224 | subsys_initcall(pcibios_init); |
1321 | 1225 | ||
1322 | unsigned long resource_fixup(struct pci_dev * dev, struct resource * res, | ||
1323 | unsigned long start, unsigned long size) | ||
1324 | { | ||
1325 | return start; | ||
1326 | } | ||
1327 | |||
1328 | void __init pcibios_fixup_bus(struct pci_bus *bus) | 1226 | void __init pcibios_fixup_bus(struct pci_bus *bus) |
1329 | { | 1227 | { |
1330 | struct pci_controller *hose = (struct pci_controller *) bus->sysdata; | 1228 | struct pci_controller *hose = (struct pci_controller *) bus->sysdata; |
@@ -1342,7 +1240,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus) | |||
1342 | if (!res->flags) { | 1240 | if (!res->flags) { |
1343 | if (io_offset) | 1241 | if (io_offset) |
1344 | printk(KERN_ERR "I/O resource not set for host" | 1242 | printk(KERN_ERR "I/O resource not set for host" |
1345 | " bridge %d\n", hose->index); | 1243 | " bridge %d\n", hose->global_number); |
1346 | res->start = 0; | 1244 | res->start = 0; |
1347 | res->end = IO_SPACE_LIMIT; | 1245 | res->end = IO_SPACE_LIMIT; |
1348 | res->flags = IORESOURCE_IO; | 1246 | res->flags = IORESOURCE_IO; |
@@ -1356,7 +1254,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus) | |||
1356 | if (i > 0) | 1254 | if (i > 0) |
1357 | continue; | 1255 | continue; |
1358 | printk(KERN_ERR "Memory resource not set for " | 1256 | printk(KERN_ERR "Memory resource not set for " |
1359 | "host bridge %d\n", hose->index); | 1257 | "host bridge %d\n", hose->global_number); |
1360 | res->start = hose->pci_mem_offset; | 1258 | res->start = hose->pci_mem_offset; |
1361 | res->end = ~0U; | 1259 | res->end = ~0U; |
1362 | res->flags = IORESOURCE_MEM; | 1260 | res->flags = IORESOURCE_MEM; |
@@ -1370,7 +1268,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus) | |||
1370 | for (i = 0; i < 4; ++i) { | 1268 | for (i = 0; i < 4; ++i) { |
1371 | if ((res = bus->resource[i]) == NULL) | 1269 | if ((res = bus->resource[i]) == NULL) |
1372 | continue; | 1270 | continue; |
1373 | if (!res->flags) | 1271 | if (!res->flags || bus->self->transparent) |
1374 | continue; | 1272 | continue; |
1375 | if (io_offset && (res->flags & IORESOURCE_IO)) { | 1273 | if (io_offset && (res->flags & IORESOURCE_IO)) { |
1376 | res->start += io_offset; | 1274 | res->start += io_offset; |
@@ -1395,11 +1293,6 @@ void __init pcibios_fixup_bus(struct pci_bus *bus) | |||
1395 | } | 1293 | } |
1396 | } | 1294 | } |
1397 | 1295 | ||
1398 | char __init *pcibios_setup(char *str) | ||
1399 | { | ||
1400 | return str; | ||
1401 | } | ||
1402 | |||
1403 | /* the next one is stolen from the alpha port... */ | 1296 | /* the next one is stolen from the alpha port... */ |
1404 | void __init | 1297 | void __init |
1405 | pcibios_update_irq(struct pci_dev *dev, int irq) | 1298 | pcibios_update_irq(struct pci_dev *dev, int irq) |
@@ -1408,64 +1301,6 @@ pcibios_update_irq(struct pci_dev *dev, int irq) | |||
1408 | /* XXX FIXME - update OF device tree node interrupt property */ | 1301 | /* XXX FIXME - update OF device tree node interrupt property */ |
1409 | } | 1302 | } |
1410 | 1303 | ||
1411 | #ifdef CONFIG_PPC_MERGE | ||
1412 | /* XXX This is a copy of the ppc64 version. This is temporary until we start | ||
1413 | * merging the 2 PCI layers | ||
1414 | */ | ||
1415 | /* | ||
1416 | * Reads the interrupt pin to determine if interrupt is use by card. | ||
1417 | * If the interrupt is used, then gets the interrupt line from the | ||
1418 | * openfirmware and sets it in the pci_dev and pci_config line. | ||
1419 | */ | ||
1420 | int pci_read_irq_line(struct pci_dev *pci_dev) | ||
1421 | { | ||
1422 | struct of_irq oirq; | ||
1423 | unsigned int virq; | ||
1424 | |||
1425 | DBG("Try to map irq for %s...\n", pci_name(pci_dev)); | ||
1426 | |||
1427 | /* Try to get a mapping from the device-tree */ | ||
1428 | if (of_irq_map_pci(pci_dev, &oirq)) { | ||
1429 | u8 line, pin; | ||
1430 | |||
1431 | /* If that fails, lets fallback to what is in the config | ||
1432 | * space and map that through the default controller. We | ||
1433 | * also set the type to level low since that's what PCI | ||
1434 | * interrupts are. If your platform does differently, then | ||
1435 | * either provide a proper interrupt tree or don't use this | ||
1436 | * function. | ||
1437 | */ | ||
1438 | if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &pin)) | ||
1439 | return -1; | ||
1440 | if (pin == 0) | ||
1441 | return -1; | ||
1442 | if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &line) || | ||
1443 | line == 0xff) { | ||
1444 | return -1; | ||
1445 | } | ||
1446 | DBG(" -> no map ! Using irq line %d from PCI config\n", line); | ||
1447 | |||
1448 | virq = irq_create_mapping(NULL, line); | ||
1449 | if (virq != NO_IRQ) | ||
1450 | set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); | ||
1451 | } else { | ||
1452 | DBG(" -> got one, spec %d cells (0x%08x...) on %s\n", | ||
1453 | oirq.size, oirq.specifier[0], oirq.controller->full_name); | ||
1454 | |||
1455 | virq = irq_create_of_mapping(oirq.controller, oirq.specifier, | ||
1456 | oirq.size); | ||
1457 | } | ||
1458 | if(virq == NO_IRQ) { | ||
1459 | DBG(" -> failed to map !\n"); | ||
1460 | return -1; | ||
1461 | } | ||
1462 | pci_dev->irq = virq; | ||
1463 | |||
1464 | return 0; | ||
1465 | } | ||
1466 | EXPORT_SYMBOL(pci_read_irq_line); | ||
1467 | #endif /* CONFIG_PPC_MERGE */ | ||
1468 | |||
1469 | int pcibios_enable_device(struct pci_dev *dev, int mask) | 1304 | int pcibios_enable_device(struct pci_dev *dev, int mask) |
1470 | { | 1305 | { |
1471 | u16 cmd, old_cmd; | 1306 | u16 cmd, old_cmd; |
@@ -1497,281 +1332,17 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) | |||
1497 | return 0; | 1332 | return 0; |
1498 | } | 1333 | } |
1499 | 1334 | ||
1500 | struct pci_controller* | 1335 | static struct pci_controller* |
1501 | pci_bus_to_hose(int bus) | 1336 | pci_bus_to_hose(int bus) |
1502 | { | 1337 | { |
1503 | struct pci_controller* hose = hose_head; | 1338 | struct pci_controller *hose, *tmp; |
1504 | 1339 | ||
1505 | for (; hose; hose = hose->next) | 1340 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) |
1506 | if (bus >= hose->first_busno && bus <= hose->last_busno) | 1341 | if (bus >= hose->first_busno && bus <= hose->last_busno) |
1507 | return hose; | 1342 | return hose; |
1508 | return NULL; | 1343 | return NULL; |
1509 | } | 1344 | } |
1510 | 1345 | ||
1511 | void __iomem * | ||
1512 | pci_bus_io_base(unsigned int bus) | ||
1513 | { | ||
1514 | struct pci_controller *hose; | ||
1515 | |||
1516 | hose = pci_bus_to_hose(bus); | ||
1517 | if (!hose) | ||
1518 | return NULL; | ||
1519 | return hose->io_base_virt; | ||
1520 | } | ||
1521 | |||
1522 | unsigned long | ||
1523 | pci_bus_io_base_phys(unsigned int bus) | ||
1524 | { | ||
1525 | struct pci_controller *hose; | ||
1526 | |||
1527 | hose = pci_bus_to_hose(bus); | ||
1528 | if (!hose) | ||
1529 | return 0; | ||
1530 | return hose->io_base_phys; | ||
1531 | } | ||
1532 | |||
1533 | unsigned long | ||
1534 | pci_bus_mem_base_phys(unsigned int bus) | ||
1535 | { | ||
1536 | struct pci_controller *hose; | ||
1537 | |||
1538 | hose = pci_bus_to_hose(bus); | ||
1539 | if (!hose) | ||
1540 | return 0; | ||
1541 | return hose->pci_mem_offset; | ||
1542 | } | ||
1543 | |||
1544 | unsigned long | ||
1545 | pci_resource_to_bus(struct pci_dev *pdev, struct resource *res) | ||
1546 | { | ||
1547 | /* Hack alert again ! See comments in chrp_pci.c | ||
1548 | */ | ||
1549 | struct pci_controller* hose = | ||
1550 | (struct pci_controller *)pdev->sysdata; | ||
1551 | if (hose && res->flags & IORESOURCE_MEM) | ||
1552 | return res->start - hose->pci_mem_offset; | ||
1553 | /* We may want to do something with IOs here... */ | ||
1554 | return res->start; | ||
1555 | } | ||
1556 | |||
1557 | |||
1558 | static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, | ||
1559 | resource_size_t *offset, | ||
1560 | enum pci_mmap_state mmap_state) | ||
1561 | { | ||
1562 | struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); | ||
1563 | unsigned long io_offset = 0; | ||
1564 | int i, res_bit; | ||
1565 | |||
1566 | if (hose == 0) | ||
1567 | return NULL; /* should never happen */ | ||
1568 | |||
1569 | /* If memory, add on the PCI bridge address offset */ | ||
1570 | if (mmap_state == pci_mmap_mem) { | ||
1571 | #if 0 /* See comment in pci_resource_to_user() for why this is disabled */ | ||
1572 | *offset += hose->pci_mem_offset; | ||
1573 | #endif | ||
1574 | res_bit = IORESOURCE_MEM; | ||
1575 | } else { | ||
1576 | io_offset = hose->io_base_virt - (void __iomem *)_IO_BASE; | ||
1577 | *offset += io_offset; | ||
1578 | res_bit = IORESOURCE_IO; | ||
1579 | } | ||
1580 | |||
1581 | /* | ||
1582 | * Check that the offset requested corresponds to one of the | ||
1583 | * resources of the device. | ||
1584 | */ | ||
1585 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) { | ||
1586 | struct resource *rp = &dev->resource[i]; | ||
1587 | int flags = rp->flags; | ||
1588 | |||
1589 | /* treat ROM as memory (should be already) */ | ||
1590 | if (i == PCI_ROM_RESOURCE) | ||
1591 | flags |= IORESOURCE_MEM; | ||
1592 | |||
1593 | /* Active and same type? */ | ||
1594 | if ((flags & res_bit) == 0) | ||
1595 | continue; | ||
1596 | |||
1597 | /* In the range of this resource? */ | ||
1598 | if (*offset < (rp->start & PAGE_MASK) || *offset > rp->end) | ||
1599 | continue; | ||
1600 | |||
1601 | /* found it! construct the final physical address */ | ||
1602 | if (mmap_state == pci_mmap_io) | ||
1603 | *offset += hose->io_base_phys - io_offset; | ||
1604 | return rp; | ||
1605 | } | ||
1606 | |||
1607 | return NULL; | ||
1608 | } | ||
1609 | |||
1610 | /* | ||
1611 | * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci | ||
1612 | * device mapping. | ||
1613 | */ | ||
1614 | static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, | ||
1615 | pgprot_t protection, | ||
1616 | enum pci_mmap_state mmap_state, | ||
1617 | int write_combine) | ||
1618 | { | ||
1619 | unsigned long prot = pgprot_val(protection); | ||
1620 | |||
1621 | /* Write combine is always 0 on non-memory space mappings. On | ||
1622 | * memory space, if the user didn't pass 1, we check for a | ||
1623 | * "prefetchable" resource. This is a bit hackish, but we use | ||
1624 | * this to workaround the inability of /sysfs to provide a write | ||
1625 | * combine bit | ||
1626 | */ | ||
1627 | if (mmap_state != pci_mmap_mem) | ||
1628 | write_combine = 0; | ||
1629 | else if (write_combine == 0) { | ||
1630 | if (rp->flags & IORESOURCE_PREFETCH) | ||
1631 | write_combine = 1; | ||
1632 | } | ||
1633 | |||
1634 | /* XXX would be nice to have a way to ask for write-through */ | ||
1635 | prot |= _PAGE_NO_CACHE; | ||
1636 | if (write_combine) | ||
1637 | prot &= ~_PAGE_GUARDED; | ||
1638 | else | ||
1639 | prot |= _PAGE_GUARDED; | ||
1640 | |||
1641 | return __pgprot(prot); | ||
1642 | } | ||
1643 | |||
1644 | /* | ||
1645 | * This one is used by /dev/mem and fbdev who have no clue about the | ||
1646 | * PCI device, it tries to find the PCI device first and calls the | ||
1647 | * above routine | ||
1648 | */ | ||
1649 | pgprot_t pci_phys_mem_access_prot(struct file *file, | ||
1650 | unsigned long pfn, | ||
1651 | unsigned long size, | ||
1652 | pgprot_t protection) | ||
1653 | { | ||
1654 | struct pci_dev *pdev = NULL; | ||
1655 | struct resource *found = NULL; | ||
1656 | unsigned long prot = pgprot_val(protection); | ||
1657 | unsigned long offset = pfn << PAGE_SHIFT; | ||
1658 | int i; | ||
1659 | |||
1660 | if (page_is_ram(pfn)) | ||
1661 | return __pgprot(prot); | ||
1662 | |||
1663 | prot |= _PAGE_NO_CACHE | _PAGE_GUARDED; | ||
1664 | |||
1665 | for_each_pci_dev(pdev) { | ||
1666 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) { | ||
1667 | struct resource *rp = &pdev->resource[i]; | ||
1668 | int flags = rp->flags; | ||
1669 | |||
1670 | /* Active and same type? */ | ||
1671 | if ((flags & IORESOURCE_MEM) == 0) | ||
1672 | continue; | ||
1673 | /* In the range of this resource? */ | ||
1674 | if (offset < (rp->start & PAGE_MASK) || | ||
1675 | offset > rp->end) | ||
1676 | continue; | ||
1677 | found = rp; | ||
1678 | break; | ||
1679 | } | ||
1680 | if (found) | ||
1681 | break; | ||
1682 | } | ||
1683 | if (found) { | ||
1684 | if (found->flags & IORESOURCE_PREFETCH) | ||
1685 | prot &= ~_PAGE_GUARDED; | ||
1686 | pci_dev_put(pdev); | ||
1687 | } | ||
1688 | |||
1689 | DBG("non-PCI map for %lx, prot: %lx\n", offset, prot); | ||
1690 | |||
1691 | return __pgprot(prot); | ||
1692 | } | ||
1693 | |||
1694 | |||
1695 | /* | ||
1696 | * Perform the actual remap of the pages for a PCI device mapping, as | ||
1697 | * appropriate for this architecture. The region in the process to map | ||
1698 | * is described by vm_start and vm_end members of VMA, the base physical | ||
1699 | * address is found in vm_pgoff. | ||
1700 | * The pci device structure is provided so that architectures may make mapping | ||
1701 | * decisions on a per-device or per-bus basis. | ||
1702 | * | ||
1703 | * Returns a negative error code on failure, zero on success. | ||
1704 | */ | ||
1705 | int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | ||
1706 | enum pci_mmap_state mmap_state, | ||
1707 | int write_combine) | ||
1708 | { | ||
1709 | resource_size_t offset = vma->vm_pgoff << PAGE_SHIFT; | ||
1710 | struct resource *rp; | ||
1711 | int ret; | ||
1712 | |||
1713 | rp = __pci_mmap_make_offset(dev, &offset, mmap_state); | ||
1714 | if (rp == NULL) | ||
1715 | return -EINVAL; | ||
1716 | |||
1717 | vma->vm_pgoff = offset >> PAGE_SHIFT; | ||
1718 | vma->vm_page_prot = __pci_mmap_set_pgprot(dev, rp, | ||
1719 | vma->vm_page_prot, | ||
1720 | mmap_state, write_combine); | ||
1721 | |||
1722 | ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, | ||
1723 | vma->vm_end - vma->vm_start, vma->vm_page_prot); | ||
1724 | |||
1725 | return ret; | ||
1726 | } | ||
1727 | |||
1728 | /* Obsolete functions. Should be removed once the symbios driver | ||
1729 | * is fixed | ||
1730 | */ | ||
1731 | unsigned long | ||
1732 | phys_to_bus(unsigned long pa) | ||
1733 | { | ||
1734 | struct pci_controller *hose; | ||
1735 | int i; | ||
1736 | |||
1737 | for (hose = hose_head; hose; hose = hose->next) { | ||
1738 | for (i = 0; i < 3; ++i) { | ||
1739 | if (pa >= hose->mem_resources[i].start | ||
1740 | && pa <= hose->mem_resources[i].end) { | ||
1741 | /* | ||
1742 | * XXX the hose->pci_mem_offset really | ||
1743 | * only applies to mem_resources[0]. | ||
1744 | * We need a way to store an offset for | ||
1745 | * the others. -- paulus | ||
1746 | */ | ||
1747 | if (i == 0) | ||
1748 | pa -= hose->pci_mem_offset; | ||
1749 | return pa; | ||
1750 | } | ||
1751 | } | ||
1752 | } | ||
1753 | /* hmmm, didn't find it */ | ||
1754 | return 0; | ||
1755 | } | ||
1756 | |||
1757 | unsigned long | ||
1758 | pci_phys_to_bus(unsigned long pa, int busnr) | ||
1759 | { | ||
1760 | struct pci_controller* hose = pci_bus_to_hose(busnr); | ||
1761 | if (!hose) | ||
1762 | return pa; | ||
1763 | return pa - hose->pci_mem_offset; | ||
1764 | } | ||
1765 | |||
1766 | unsigned long | ||
1767 | pci_bus_to_phys(unsigned int ba, int busnr) | ||
1768 | { | ||
1769 | struct pci_controller* hose = pci_bus_to_hose(busnr); | ||
1770 | if (!hose) | ||
1771 | return ba; | ||
1772 | return ba + hose->pci_mem_offset; | ||
1773 | } | ||
1774 | |||
1775 | /* Provide information on locations of various I/O regions in physical | 1346 | /* Provide information on locations of various I/O regions in physical |
1776 | * memory. Do this on a per-card basis so that we choose the right | 1347 | * memory. Do this on a per-card basis so that we choose the right |
1777 | * root bridge. | 1348 | * root bridge. |
@@ -1814,62 +1385,11 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn) | |||
1814 | return result; | 1385 | return result; |
1815 | } | 1386 | } |
1816 | 1387 | ||
1817 | void pci_resource_to_user(const struct pci_dev *dev, int bar, | ||
1818 | const struct resource *rsrc, | ||
1819 | resource_size_t *start, resource_size_t *end) | ||
1820 | { | ||
1821 | struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); | ||
1822 | resource_size_t offset = 0; | ||
1823 | |||
1824 | if (hose == NULL) | ||
1825 | return; | ||
1826 | |||
1827 | if (rsrc->flags & IORESOURCE_IO) | ||
1828 | offset = (unsigned long)hose->io_base_virt - _IO_BASE; | ||
1829 | |||
1830 | /* We pass a fully fixed up address to userland for MMIO instead of | ||
1831 | * a BAR value because X is lame and expects to be able to use that | ||
1832 | * to pass to /dev/mem ! | ||
1833 | * | ||
1834 | * That means that we'll have potentially 64 bits values where some | ||
1835 | * userland apps only expect 32 (like X itself since it thinks only | ||
1836 | * Sparc has 64 bits MMIO) but if we don't do that, we break it on | ||
1837 | * 32 bits CHRPs :-( | ||
1838 | * | ||
1839 | * Hopefully, the sysfs insterface is immune to that gunk. Once X | ||
1840 | * has been fixed (and the fix spread enough), we can re-enable the | ||
1841 | * 2 lines below and pass down a BAR value to userland. In that case | ||
1842 | * we'll also have to re-enable the matching code in | ||
1843 | * __pci_mmap_make_offset(). | ||
1844 | * | ||
1845 | * BenH. | ||
1846 | */ | ||
1847 | #if 0 | ||
1848 | else if (rsrc->flags & IORESOURCE_MEM) | ||
1849 | offset = hose->pci_mem_offset; | ||
1850 | #endif | ||
1851 | |||
1852 | *start = rsrc->start - offset; | ||
1853 | *end = rsrc->end - offset; | ||
1854 | } | ||
1855 | |||
1856 | void __init pci_init_resource(struct resource *res, resource_size_t start, | ||
1857 | resource_size_t end, int flags, char *name) | ||
1858 | { | ||
1859 | res->start = start; | ||
1860 | res->end = end; | ||
1861 | res->flags = flags; | ||
1862 | res->name = name; | ||
1863 | res->parent = NULL; | ||
1864 | res->sibling = NULL; | ||
1865 | res->child = NULL; | ||
1866 | } | ||
1867 | |||
1868 | unsigned long pci_address_to_pio(phys_addr_t address) | 1388 | unsigned long pci_address_to_pio(phys_addr_t address) |
1869 | { | 1389 | { |
1870 | struct pci_controller* hose = hose_head; | 1390 | struct pci_controller *hose, *tmp; |
1871 | 1391 | ||
1872 | for (; hose; hose = hose->next) { | 1392 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { |
1873 | unsigned int size = hose->io_resource.end - | 1393 | unsigned int size = hose->io_resource.end - |
1874 | hose->io_resource.start + 1; | 1394 | hose->io_resource.start + 1; |
1875 | if (address >= hose->io_base_phys && | 1395 | if (address >= hose->io_base_phys && |