~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/pci/setup-res.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 1
 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 for %s\n", i, dev->name);
119                         return -EBUSY;
120                 }
121         }
122 
123         DBGC(("  got res[%lx:%lx] for resource %d of %s\n", res->start,
124                                                 res->end, i, dev->name));
125 
126         return 0;
127 }
128 
129 /* Sort resources of a given type by alignment */
130 void __init
131 pdev_sort_resources(struct pci_dev *dev,
132                     struct resource_list *head, u32 type_mask)
133 {
134         int i;
135 
136         for (i = 0; i < PCI_NUM_RESOURCES; i++) {
137                 struct resource *r;
138                 struct resource_list *list, *tmp;
139                 unsigned long r_size;
140 
141                 /* PCI-PCI bridges may have I/O ports or
142                    memory on the primary bus */
143                 if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI &&
144                                                 i >= PCI_BRIDGE_RESOURCES)
145                         continue;
146 
147                 r = &dev->resource[i];
148                 r_size = r->end - r->start;
149                 
150                 if (!(r->flags & type_mask) || r->parent)
151                         continue;
152                 if (!r_size) {
153                         printk(KERN_WARNING "PCI: Ignore bogus resource %d "
154                                          "[%lx:%lx] of %s\n",
155                                           i, r->start, r->end, dev->name);
156                         continue;
157                 }
158                 for (list = head; ; list = list->next) {
159                         unsigned long size = 0;
160                         struct resource_list *ln = list->next;
161 
162                         if (ln)
163                                 size = ln->res->end - ln->res->start;
164                         if (r_size > size) {
165                                 tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
166                                 tmp->next = ln;
167                                 tmp->res = r;
168                                 tmp->dev = dev;
169                                 list->next = tmp;
170                                 break;
171                         }
172                 }
173         }
174 }
175 
176 void __init
177 pdev_enable_device(struct pci_dev *dev)
178 {
179         u32 reg;
180         u16 cmd;
181         int i;
182 
183         DBGC(("PCI enable device: (%s)\n", dev->name));
184 
185         pci_read_config_word(dev, PCI_COMMAND, &cmd);
186 
187         for (i = 0; i < PCI_NUM_RESOURCES; i++) {
188                 struct resource *res = &dev->resource[i];
189 
190                 if (res->flags & IORESOURCE_IO)
191                         cmd |= PCI_COMMAND_IO;
192                 else if (res->flags & IORESOURCE_MEM)
193                         cmd |= PCI_COMMAND_MEMORY;
194         }
195 
196         /* Special case, disable the ROM.  Several devices act funny
197            (ie. do not respond to memory space writes) when it is left
198            enabled.  A good example are QlogicISP adapters.  */
199 
200         if (dev->rom_base_reg) {
201                 pci_read_config_dword(dev, dev->rom_base_reg, &reg);
202                 reg &= ~PCI_ROM_ADDRESS_ENABLE;
203                 pci_write_config_dword(dev, dev->rom_base_reg, reg);
204                 dev->resource[PCI_ROM_RESOURCE].flags &= ~PCI_ROM_ADDRESS_ENABLE;
205         }
206 
207         /* All of these (may) have I/O scattered all around and may not
208            use I/O base address registers at all.  So we just have to
209            always enable IO to these devices.  */
210         if ((dev->class >> 8) == PCI_CLASS_NOT_DEFINED
211             || (dev->class >> 8) == PCI_CLASS_NOT_DEFINED_VGA
212             || (dev->class >> 8) == PCI_CLASS_STORAGE_IDE
213             || (dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
214                 cmd |= PCI_COMMAND_IO;
215         }
216 
217         /* ??? Always turn on bus mastering.  If the device doesn't support
218            it, the bit will go into the bucket. */
219         cmd |= PCI_COMMAND_MASTER;
220 
221         /* Set the cache line and default latency (32).  */
222         pci_write_config_word(dev, PCI_CACHE_LINE_SIZE,
223                         (32 << 8) | (L1_CACHE_BYTES / sizeof(u32)));
224 
225         /* Enable the appropriate bits in the PCI command register.  */
226         pci_write_config_word(dev, PCI_COMMAND, cmd);
227 
228         DBGC(("  cmd reg 0x%x\n", cmd));
229 }
230 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.