home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / lxapi32.zip / Linux / PCI / setup-bus.c < prev    next >
C/C++ Source or Header  |  2001-10-04  |  7KB  |  250 lines

  1. /*
  2.  *    drivers/pci/setup-bus.c
  3.  *
  4.  * Extruded from code written by
  5.  *      Dave Rusling (david.rusling@reo.mts.dec.com)
  6.  *      David Mosberger (davidm@cs.arizona.edu)
  7.  *    David Miller (davem@redhat.com)
  8.  *
  9.  * Support routines for initializing a PCI subsystem.
  10.  */
  11.  
  12. /*
  13.  * Nov 2000, Ivan Kokshaysky <ink@jurassic.park.msu.ru>
  14.  *         PCI-PCI bridges cleanup, sorted resource allocation
  15.  */
  16.  
  17. #include <linux/init.h>
  18. #include <linux/kernel.h>
  19. #include <linux/pci.h>
  20. #include <linux/errno.h>
  21. #include <linux/ioport.h>
  22. #include <linux/cache.h>
  23. #include <linux/slab.h>
  24.  
  25.  
  26. #define DEBUG_CONFIG 0
  27. #if DEBUG_CONFIG
  28. # define DBGC(args)     printk args
  29. #else
  30. # define DBGC(args)
  31. #endif
  32.  
  33. #define ROUND_UP(x, a)        (((x) + (a) - 1) & ~((a) - 1))
  34.  
  35. static int __init
  36. pbus_assign_resources_sorted(struct pci_bus *bus,
  37.                  struct pbus_set_ranges_data *ranges)
  38. {
  39.     struct list_head *ln;
  40.     struct resource *res;
  41.     struct resource_list head_io, head_mem, *list, *tmp;
  42.     unsigned long io_reserved = 0, mem_reserved = 0;
  43.     int idx, found_vga = 0;
  44.  
  45.     head_io.next = head_mem.next = NULL;
  46.     for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
  47.         struct pci_dev *dev = pci_dev_b(ln);
  48.         u16 class = dev->class >> 8;
  49.         u16 cmd;
  50.  
  51.         /* First, disable the device to avoid side
  52.            effects of possibly overlapping I/O and
  53.            memory ranges.
  54.            Leave VGA enabled - for obvious reason. :-)
  55.            Same with all sorts of bridges - they may
  56.            have VGA behind them.  */
  57.         if (class == PCI_CLASS_DISPLAY_VGA
  58.                 || class == PCI_CLASS_NOT_DEFINED_VGA)
  59.             found_vga = 1;
  60.         else if (class >> 8 != PCI_BASE_CLASS_BRIDGE) {
  61.             pci_read_config_word(dev, PCI_COMMAND, &cmd);
  62.             cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY
  63.                         | PCI_COMMAND_MASTER);
  64.             pci_write_config_word(dev, PCI_COMMAND, cmd);
  65.         }
  66.  
  67.         /* Reserve some resources for CardBus.
  68.            Are these values reasonable? */
  69.         if (class == PCI_CLASS_BRIDGE_CARDBUS) {
  70.             io_reserved += 8*1024;
  71.             mem_reserved += 32*1024*1024;
  72.             continue;
  73.         }
  74.  
  75.         pdev_sort_resources(dev, &head_io, IORESOURCE_IO);
  76.         pdev_sort_resources(dev, &head_mem, IORESOURCE_MEM);
  77.     }
  78.  
  79.     for (list = head_io.next; list;) {
  80.         res = list->res;
  81.         idx = res - &list->dev->resource[0];
  82.         if (pci_assign_resource(list->dev, idx) == 0
  83.             && ranges->io_end < res->end)
  84.             ranges->io_end = res->end;
  85.         tmp = list;
  86.         list = list->next;
  87.         kfree(tmp);
  88.     }
  89.     for (list = head_mem.next; list;) {
  90.         res = list->res;
  91.         idx = res - &list->dev->resource[0];
  92.         if (pci_assign_resource(list->dev, idx) == 0
  93.             && ranges->mem_end < res->end)
  94.             ranges->mem_end = res->end;
  95.         tmp = list;
  96.         list = list->next;
  97.         kfree(tmp);
  98.     }
  99.  
  100.     ranges->io_end += io_reserved;
  101.     ranges->mem_end += mem_reserved;
  102.  
  103.     /* PCI-to-PCI Bridge Architecture Specification rev. 1.1 (1998)
  104.        requires that if there is no I/O ports or memory behind the
  105.        bridge, corresponding range must be turned off by writing base
  106.        value greater than limit to the bridge's base/limit registers.  */
  107. #if 1
  108.     /* But assuming that some hardware designed before 1998 might
  109.        not support this (very unlikely - at least all DEC bridges
  110.        are ok and I believe that was standard de-facto. -ink), we
  111.        must allow for at least one unit.  */
  112.     if (ranges->io_end == ranges->io_start)
  113.         ranges->io_end += 1;
  114.     if (ranges->mem_end == ranges->mem_start)
  115.         ranges->mem_end += 1;
  116. #endif
  117.     ranges->io_end = ROUND_UP(ranges->io_end, 4*1024);
  118.     ranges->mem_end = ROUND_UP(ranges->mem_end, 1024*1024);
  119.  
  120.     return found_vga;
  121. }
  122.  
  123. /* Initialize bridges with base/limit values we have collected */
  124. static void __init
  125. pci_setup_bridge(struct pci_bus *bus)
  126. {
  127.     struct pbus_set_ranges_data ranges;
  128.     struct pci_dev *bridge = bus->self;
  129.     u32 l;
  130.  
  131.     if (!bridge || (bridge->class >> 8) != PCI_CLASS_BRIDGE_PCI)
  132.         return;
  133.     ranges.io_start = bus->resource[0]->start;
  134.     ranges.io_end = bus->resource[0]->end;
  135.     ranges.mem_start = bus->resource[1]->start;
  136.     ranges.mem_end = bus->resource[1]->end;
  137.     pcibios_fixup_pbus_ranges(bus, &ranges);
  138.  
  139.     DBGC((KERN_ERR "PCI: Bus %d, bridge: %s\n", bus->number, bridge->name));
  140.     DBGC((KERN_ERR "  IO window: %04lx-%04lx\n", ranges.io_start, ranges.io_end));
  141.     DBGC((KERN_ERR "  MEM window: %08lx-%08lx\n", ranges.mem_start, ranges.mem_end));
  142.  
  143.     /* Set up the top and bottom of the PCI I/O segment for this bus. */
  144.     pci_read_config_dword(bridge, PCI_IO_BASE, &l);
  145.     l &= 0xffff0000;
  146.     l |= (ranges.io_start >> 8) & 0x00f0;
  147.     l |= ranges.io_end & 0xf000;
  148.     pci_write_config_dword(bridge, PCI_IO_BASE, l);
  149.  
  150.     /* Clear upper 16 bits of I/O base/limit. */
  151.     pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0);
  152.  
  153.     /* Clear out the upper 32 bits of PREF base/limit. */
  154.     pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, 0);
  155.     pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0);
  156.  
  157.     /* Set up the top and bottom of the PCI Memory segment
  158.        for this bus. */
  159.     l = (ranges.mem_start >> 16) & 0xfff0;
  160.     l |= ranges.mem_end & 0xfff00000;
  161.     pci_write_config_dword(bridge, PCI_MEMORY_BASE, l);
  162.  
  163.     /* Set up PREF base/limit. */
  164.     l = (bus->resource[2]->start >> 16) & 0xfff0;
  165.     l |= bus->resource[2]->end & 0xfff00000;
  166.     pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l);
  167.  
  168.     /* Check if we have VGA behind the bridge.
  169.        Enable ISA in either case. */
  170.     l = (bus->resource[0]->flags & IORESOURCE_BUS_HAS_VGA) ? 0x0c : 0x04;
  171.     pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, l);
  172. }
  173.  
  174. static void __init
  175. pbus_assign_resources(struct pci_bus *bus, struct pbus_set_ranges_data *ranges)
  176. {
  177.     struct list_head *ln;
  178.     int found_vga = pbus_assign_resources_sorted(bus, ranges);
  179.  
  180.     if (!ranges->found_vga && found_vga) {
  181.         struct pci_bus *b;
  182.  
  183.         ranges->found_vga = 1;
  184.         /* Propogate presence of the VGA to upstream bridges */
  185.         for (b = bus; b->parent; b = b->parent) {
  186. #if 0
  187.             /* ? Do we actually need to enable PF memory? */
  188.             b->resource[2]->start = 0;
  189. #endif
  190.             b->resource[0]->flags |= IORESOURCE_BUS_HAS_VGA;
  191.         }
  192.     }
  193.     for (ln=bus->children.next; ln != &bus->children; ln=ln->next) {
  194.         struct pci_bus *b = pci_bus_b(ln);
  195.  
  196.         b->resource[0]->start = ranges->io_start = ranges->io_end;
  197.         b->resource[1]->start = ranges->mem_start = ranges->mem_end;
  198.  
  199.         pbus_assign_resources(b, ranges);
  200.  
  201.         b->resource[0]->end = ranges->io_end - 1;
  202.         b->resource[1]->end = ranges->mem_end - 1;
  203.  
  204.         pci_setup_bridge(b);
  205.     }
  206. }
  207.  
  208. void __init
  209. pci_assign_unassigned_resources(void)
  210. {
  211.     struct pbus_set_ranges_data ranges;
  212.     struct list_head *ln;
  213.     struct pci_dev *dev;
  214.  
  215.     for(ln=pci_root_buses.next; ln != &pci_root_buses; ln=ln->next) {
  216.         struct pci_bus *b = pci_bus_b(ln);
  217.  
  218.         ranges.io_start = b->resource[0]->start + PCIBIOS_MIN_IO;
  219.         ranges.mem_start = b->resource[1]->start + PCIBIOS_MIN_MEM;
  220.         ranges.io_end = ranges.io_start;
  221.         ranges.mem_end = ranges.mem_start;
  222.         ranges.found_vga = 0;
  223.         pbus_assign_resources(b, &ranges);
  224.     }
  225.     pci_for_each_dev(dev) {
  226.         pdev_enable_device(dev);
  227.     }
  228. }
  229.  
  230. /* Check whether the bridge supports I/O forwarding.
  231.    If not, its I/O base/limit register must be
  232.    read-only and read as 0. */
  233. unsigned long __init
  234. pci_bridge_check_io(struct pci_dev *bridge)
  235. {
  236.     u16 io;
  237.  
  238.     pci_read_config_word(bridge, PCI_IO_BASE, &io);
  239.     if (!io) {
  240.         pci_write_config_word(bridge, PCI_IO_BASE, 0xf0f0);
  241.         pci_read_config_word(bridge, PCI_IO_BASE, &io);
  242.         pci_write_config_word(bridge, PCI_IO_BASE, 0x0);
  243.     }
  244.     if (io)
  245.         return IORESOURCE_IO;
  246.     printk(KERN_WARNING "PCI: bridge %s does not support I/O forwarding!\n",
  247.                 bridge->name);
  248.     return 0;
  249. }
  250.