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

  1. /*
  2.  *    drivers/pci/setup-res.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. /* fixed for multiple pci buses, 1999 Andrea Arcangeli <andrea@suse.de> */
  13.  
  14. /*
  15.  * Nov 2000, Ivan Kokshaysky <ink@jurassic.park.msu.ru>
  16.  *         Resource sorting
  17.  */
  18.  
  19. #include <linux/init.h>
  20. #include <linux/kernel.h>
  21. #include <linux/pci.h>
  22. #include <linux/errno.h>
  23. #include <linux/ioport.h>
  24. #include <linux/cache.h>
  25. #include <linux/slab.h>
  26.  
  27.  
  28. #define DEBUG_CONFIG 0
  29. #if DEBUG_CONFIG
  30. # define DBGC(args)     printk args
  31. #else
  32. # define DBGC(args)
  33. #endif
  34.  
  35.  
  36. int __init
  37. pci_claim_resource(struct pci_dev *dev, int resource)
  38. {
  39.         struct resource *res = &dev->resource[resource];
  40.     struct resource *root = pci_find_parent_resource(dev, res);
  41.     int err;
  42.  
  43.     err = -EINVAL;
  44.     if (root != NULL) {
  45.         err = request_resource(root, res);
  46.         if (err) {
  47.             printk(KERN_ERR "PCI: Address space collision on "
  48.                    "region %d of device %s [%lx:%lx]\n",
  49.                    resource, dev->name, res->start, res->end);
  50.         }
  51.     } else {
  52.         printk(KERN_ERR "PCI: No parent found for region %d "
  53.                "of device %s\n", resource, dev->name);
  54.     }
  55.  
  56.     return err;
  57. }
  58.  
  59. /*
  60.  * Given the PCI bus a device resides on, try to
  61.  * find an acceptable resource allocation for a
  62.  * specific device resource..
  63.  */
  64. static int pci_assign_bus_resource(const struct pci_bus *bus,
  65.     struct pci_dev *dev,
  66.     struct resource *res,
  67.     unsigned long size,
  68.     unsigned long min,
  69.     unsigned int type_mask,
  70.     int resno)
  71. {
  72.     int i;
  73.  
  74.     type_mask |= IORESOURCE_IO | IORESOURCE_MEM;
  75.     for (i = 0 ; i < 4; i++) {
  76.         struct resource *r = bus->resource[i];
  77.         if (!r)
  78.             continue;
  79.  
  80.         /* type_mask must match */
  81.         if ((res->flags ^ r->flags) & type_mask)
  82.             continue;
  83.  
  84.         /* We cannot allocate a non-prefetching resource from a pre-fetching area */
  85.         if ((r->flags & IORESOURCE_PREFETCH) && !(res->flags & IORESOURCE_PREFETCH))
  86.             continue;
  87.  
  88.         /* Ok, try it out.. */
  89.         if (allocate_resource(r, res, size, min, -1, size, pcibios_align_resource, dev) < 0)
  90.             continue;
  91.  
  92.         /* Update PCI config space.  */
  93.         pcibios_update_resource(dev, r, res, resno);
  94.         return 0;
  95.     }
  96.     return -EBUSY;
  97. }
  98.  
  99. int 
  100. pci_assign_resource(struct pci_dev *dev, int i)
  101. {
  102.     const struct pci_bus *bus = dev->bus;
  103.     struct resource *res = dev->resource + i;
  104.     unsigned long size, min;
  105.  
  106.     size = res->end - res->start + 1;
  107.     min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
  108.  
  109.     /* First, try exact prefetching match.. */
  110.     if (pci_assign_bus_resource(bus, dev, res, size, min, IORESOURCE_PREFETCH, i) < 0) {
  111.         /*
  112.          * That failed.
  113.          *
  114.          * But a prefetching area can handle a non-prefetching
  115.          * window (it will just not perform as well).
  116.          */
  117.         if (!(res->flags & IORESOURCE_PREFETCH) || pci_assign_bus_resource(bus, dev, res, size, min, 0, i) < 0) {
  118.             printk(KERN_ERR "PCI: Failed to allocate resource %d(%lx-%lx) for %s\n",
  119.                    i, res->start, res->end, dev->slot_name);
  120.             return -EBUSY;
  121.         }
  122.     }
  123.  
  124.     DBGC((KERN_ERR "  got res[%lx:%lx] for resource %d of %s\n", res->start,
  125.                         res->end, i, dev->name));
  126.  
  127.     return 0;
  128. }
  129.  
  130. /* Sort resources of a given type by alignment */
  131. void __init
  132. pdev_sort_resources(struct pci_dev *dev,
  133.             struct resource_list *head, u32 type_mask)
  134. {
  135.     int i;
  136.  
  137.     for (i = 0; i < PCI_NUM_RESOURCES; i++) {
  138.         struct resource *r;
  139.         struct resource_list *list, *tmp;
  140.         unsigned long r_size;
  141.  
  142.         /* PCI-PCI bridges may have I/O ports or
  143.            memory on the primary bus */
  144.         if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI &&
  145.                         i >= PCI_BRIDGE_RESOURCES)
  146.             continue;
  147.  
  148.         r = &dev->resource[i];
  149.         r_size = r->end - r->start;
  150.         
  151.         if (!(r->flags & type_mask) || r->parent)
  152.             continue;
  153.         if (!r_size) {
  154.             printk(KERN_WARNING "PCI: Ignore bogus resource %d "
  155.                      "[%lx:%lx] of %s\n",
  156.                       i, r->start, r->end, dev->name);
  157.             continue;
  158.         }
  159.         for (list = head; ; list = list->next) {
  160.             unsigned long size = 0;
  161.             struct resource_list *ln = list->next;
  162.  
  163.             if (ln)
  164.                 size = ln->res->end - ln->res->start;
  165.             if (r_size > size) {
  166.                 tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
  167.                 if (!tmp) {
  168.                     printk(KERN_ERR "pdev_sort_resources(): kmalloc() failed!\n");
  169.                     continue;
  170.                 }
  171.                 tmp->next = ln;
  172.                 tmp->res = r;
  173.                 tmp->dev = dev;
  174.                 list->next = tmp;
  175.                 break;
  176.             }
  177.         }
  178.     }
  179. }
  180.  
  181. void __init
  182. pdev_enable_device(struct pci_dev *dev)
  183. {
  184.     u32 reg;
  185.     u16 cmd;
  186.     int i;
  187.  
  188.     DBGC((KERN_ERR "PCI enable device: (%s)\n", dev->name));
  189.  
  190.     pci_read_config_word(dev, PCI_COMMAND, &cmd);
  191.  
  192.     for (i = 0; i < PCI_NUM_RESOURCES; i++) {
  193.         struct resource *res = &dev->resource[i];
  194.  
  195.         if (res->flags & IORESOURCE_IO)
  196.             cmd |= PCI_COMMAND_IO;
  197.         else if (res->flags & IORESOURCE_MEM)
  198.             cmd |= PCI_COMMAND_MEMORY;
  199.     }
  200.  
  201.     /* Special case, disable the ROM.  Several devices act funny
  202.        (ie. do not respond to memory space writes) when it is left
  203.        enabled.  A good example are QlogicISP adapters.  */
  204.  
  205.     if (dev->rom_base_reg) {
  206.         pci_read_config_dword(dev, dev->rom_base_reg, ®);
  207.         reg &= ~PCI_ROM_ADDRESS_ENABLE;
  208.         pci_write_config_dword(dev, dev->rom_base_reg, reg);
  209.         dev->resource[PCI_ROM_RESOURCE].flags &= ~PCI_ROM_ADDRESS_ENABLE;
  210.     }
  211.  
  212.     /* All of these (may) have I/O scattered all around and may not
  213.        use I/O base address registers at all.  So we just have to
  214.        always enable IO to these devices.  */
  215.     if ((dev->class >> 8) == PCI_CLASS_NOT_DEFINED
  216.         || (dev->class >> 8) == PCI_CLASS_NOT_DEFINED_VGA
  217.         || (dev->class >> 8) == PCI_CLASS_STORAGE_IDE
  218.         || (dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
  219.         cmd |= PCI_COMMAND_IO;
  220.     }
  221.  
  222.     /* Do not enable bus mastering.  A device could corrupt
  223.      * system memory by DMAing before a driver is ready for it. */
  224.  
  225.     /* Set the cache line and default latency (32).  */
  226.     pci_write_config_word(dev, PCI_CACHE_LINE_SIZE,
  227.             (32 << 8) | (L1_CACHE_BYTES / sizeof(u32)));
  228.  
  229.     /* Enable the appropriate bits in the PCI command register.  */
  230.     pci_write_config_word(dev, PCI_COMMAND, cmd);
  231.  
  232.     DBGC((KERN_ERR "  cmd reg 0x%x\n", cmd));
  233. }
  234.