/* * drivers/pci/setup-res.c * * Extruded from code written by * Dave Rusling (david.rusling@reo.mts.dec.com) * David Mosberger (davidm@cs.arizona.edu) * David Miller (davem@redhat.com) * * Support routines for initializing a PCI subsystem. */ /* fixed for multiple pci buses, 1999 Andrea Arcangeli <andrea@suse.de> */ /* * Nov 2000, Ivan Kokshaysky <ink@jurassic.park.msu.ru> * Resource sorting */ #include <linux/init.h> #include <linux/kernel.h> #include <linux/pci.h> #include <linux/errno.h> #include <linux/ioport.h> #include <linux/cache.h> #include <linux/slab.h> #define DEBUG_CONFIG 1 #if DEBUG_CONFIG # define DBGC(args) printk args #else # define DBGC(args) #endif int __init 37 pci_claim_resource(struct pci_dev *dev, int resource) { struct resource *res = &dev->resource[resource]; struct resource *root = pci_find_parent_resource(dev, res); int err; err = -EINVAL; 44 if (root != NULL) { err = request_resource(root, res); 46 if (err) { printk(KERN_ERR "PCI: Address space collision on " "region %d of device %s [%lx:%lx]\n", resource, dev->name, res->start, res->end); } 51 } else { printk(KERN_ERR "PCI: No parent found for region %d " "of device %s\n", resource, dev->name); } 56 return err; } /* * Given the PCI bus a device resides on, try to * find an acceptable resource allocation for a * specific device resource.. */ 64 static int pci_assign_bus_resource(const struct pci_bus *bus, struct pci_dev *dev, struct resource *res, unsigned long size, unsigned long min, unsigned int type_mask, int resno) { int i; type_mask |= IORESOURCE_IO | IORESOURCE_MEM; 75 for (i = 0 ; i < 4; i++) { struct resource *r = bus->resource[i]; 77 if (!r) 78 continue; /* type_mask must match */ 81 if ((res->flags ^ r->flags) & type_mask) 82 continue; /* We cannot allocate a non-prefetching resource from a pre-fetching area */ 85 if ((r->flags & IORESOURCE_PREFETCH) && !(res->flags & IORESOURCE_PREFETCH)) 86 continue; /* Ok, try it out.. */ 89 if (allocate_resource(r, res, size, min, -1, size, pcibios_align_resource, dev) < 0) 90 continue; /* Update PCI config space. */ pcibios_update_resource(dev, r, res, resno); 94 return 0; } 96 return -EBUSY; } int 100 pci_assign_resource(struct pci_dev *dev, int i) { const struct pci_bus *bus = dev->bus; struct resource *res = dev->resource + i; unsigned long size, min; size = res->end - res->start + 1; min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM; /* First, try exact prefetching match.. */ 110 if (pci_assign_bus_resource(bus, dev, res, size, min, IORESOURCE_PREFETCH, i) < 0) { /* * That failed. * * But a prefetching area can handle a non-prefetching * window (it will just not perform as well). */ 117 if (!(res->flags & IORESOURCE_PREFETCH) || pci_assign_bus_resource(bus, dev, res, size, min, 0, i) < 0) { printk(KERN_ERR "PCI: Failed to allocate resource %d for %s\n", i, dev->name); 119 return -EBUSY; } } DBGC((" got res[%lx:%lx] for resource %d of %s\n", res->start, res->end, i, dev->name)); 126 return 0; } /* Sort resources of a given type by alignment */ void __init 131 pdev_sort_resources(struct pci_dev *dev, struct resource_list *head, u32 type_mask) { int i; 136 for (i = 0; i < PCI_NUM_RESOURCES; i++) { struct resource *r; struct resource_list *list, *tmp; unsigned long r_size; /* PCI-PCI bridges may have I/O ports or memory on the primary bus */ if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI && 144 i >= PCI_BRIDGE_RESOURCES) 145 continue; r = &dev->resource[i]; r_size = r->end - r->start; 150 if (!(r->flags & type_mask) || r->parent) 151 continue; 152 if (!r_size) { printk(KERN_WARNING "PCI: Ignore bogus resource %d " "[%lx:%lx] of %s\n", i, r->start, r->end, dev->name); 156 continue; } 158 for (list = head; ; list = list->next) { unsigned long size = 0; struct resource_list *ln = list->next; 162 if (ln) size = ln->res->end - ln->res->start; 164 if (r_size > size) { tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); tmp->next = ln; tmp->res = r; tmp->dev = dev; list->next = tmp; 170 break; } } } } void __init 177 pdev_enable_device(struct pci_dev *dev) { u32 reg; u16 cmd; int i; DBGC(("PCI enable device: (%s)\n", dev->name)); pci_read_config_word(dev, PCI_COMMAND, &cmd); 187 for (i = 0; i < PCI_NUM_RESOURCES; i++) { struct resource *res = &dev->resource[i]; 190 if (res->flags & IORESOURCE_IO) cmd |= PCI_COMMAND_IO; 192 else if (res->flags & IORESOURCE_MEM) cmd |= PCI_COMMAND_MEMORY; } /* Special case, disable the ROM. Several devices act funny (ie. do not respond to memory space writes) when it is left enabled. A good example are QlogicISP adapters. */ 200 if (dev->rom_base_reg) { pci_read_config_dword(dev, dev->rom_base_reg, ®); reg &= ~PCI_ROM_ADDRESS_ENABLE; pci_write_config_dword(dev, dev->rom_base_reg, reg); dev->resource[PCI_ROM_RESOURCE].flags &= ~PCI_ROM_ADDRESS_ENABLE; } /* All of these (may) have I/O scattered all around and may not use I/O base address registers at all. So we just have to always enable IO to these devices. */ if ((dev->class >> 8) == PCI_CLASS_NOT_DEFINED || (dev->class >> 8) == PCI_CLASS_NOT_DEFINED_VGA || (dev->class >> 8) == PCI_CLASS_STORAGE_IDE 213 || (dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) { cmd |= PCI_COMMAND_IO; } /* ??? Always turn on bus mastering. If the device doesn't support it, the bit will go into the bucket. */ cmd |= PCI_COMMAND_MASTER; /* Set the cache line and default latency (32). */ pci_write_config_word(dev, PCI_CACHE_LINE_SIZE, (32 << 8) | (L1_CACHE_BYTES / sizeof(u32))); /* Enable the appropriate bits in the PCI command register. */ pci_write_config_word(dev, PCI_COMMAND, cmd); DBGC((" cmd reg 0x%x\n", cmd)); }