8315ce4907c8ded30ffe17d16f8c4dedc76992e9
[coreboot.git] / src / devices / device_util.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2003-2004 Linux Networx
5  * (Written by Eric Biederman <ebiederman@lnxi.com> for Linux Networx)
6  * Copyright (C) 2003 Greg Watson <jarrah@users.sourceforge.net>
7  * Copyright (C) 2004 Li-Ta Lo <ollie@lanl.gov>
8  * Copyright (C) 2005-2006 Tyan
9  * (Written by Yinghai Lu <yhlu@tyan.com> for Tyan)
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; version 2 of the License.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
23  */
24
25 #include <console/console.h>
26 #include <device/device.h>
27 #include <device/path.h>
28 #include <device/pci.h>
29 #include <device/resource.h>
30 #include <string.h>
31
32 /**
33  * See if a device structure exists for path.
34  *
35  * @param parent The bus to find the device on.
36  * @param path The relative path from the bus to the appropriate device.
37  * @return Pointer to a device structure for the device on bus at path
38  *         or 0/NULL if no device is found.
39  */
40 device_t find_dev_path(struct bus *parent, struct device_path *path)
41 {
42         device_t child;
43         for (child = parent->children; child; child = child->sibling) {
44                 if (path_eq(path, &child->path)) {
45                         break;
46                 }
47         }
48         return child;
49 }
50
51 /**
52  * See if a device structure already exists and if not allocate it.
53  *
54  * @param parent The bus to find the device on.
55  * @param path The relative path from the bus to the appropriate device.
56  * @return Pointer to a device structure for the device on bus at path.
57  */
58 device_t alloc_find_dev(struct bus *parent, struct device_path *path)
59 {
60         device_t child;
61         child = find_dev_path(parent, path);
62         if (!child) {
63                 child = alloc_dev(parent, path);
64         }
65         return child;
66 }
67
68 /**
69  * Given a PCI bus and a devfn number, find the device structure.
70  *
71  * @param bus The bus number.
72  * @param devfn A device/function number.
73  * @return Pointer to the device structure (if found), 0 otherwise.
74  */
75 struct device *dev_find_slot(unsigned int bus, unsigned int devfn)
76 {
77         struct device *dev, *result;
78
79         result = 0;
80         for (dev = all_devices; dev; dev = dev->next) {
81                 if ((dev->path.type == DEVICE_PATH_PCI) &&
82                         (dev->bus->secondary == bus) &&
83                         (dev->path.pci.devfn == devfn)) {
84                         result = dev;
85                         break;
86                 }
87         }
88         return result;
89 }
90
91 /**
92  * Given an SMBus bus and a device number, find the device structure.
93  *
94  * @param bus The bus number.
95  * @param addr A device number.
96  * @return Pointer to the device structure (if found), 0 otherwise.
97  */
98 struct device *dev_find_slot_on_smbus(unsigned int bus, unsigned int addr)
99 {
100         struct device *dev, *result;
101
102         result = 0;
103         for (dev = all_devices; dev; dev = dev->next) {
104                 if ((dev->path.type == DEVICE_PATH_I2C) &&
105                         (dev->bus->secondary == bus) &&
106                         (dev->path.i2c.device == addr)) {
107                         result = dev;
108                         break;
109                 }
110         }
111         return result;
112 }
113
114 /**
115  * Find a device of a given vendor and type.
116  *
117  * @param vendor A PCI vendor ID (e.g. 0x8086 for Intel).
118  * @param device A PCI device ID.
119  * @param from Pointer to the device structure, used as a starting point
120  *        in the linked list of all_devices, which can be 0 to start at the
121  *        head of the list (i.e. all_devices).
122  * @return Pointer to the device struct.
123  */
124 struct device *dev_find_device(unsigned int vendor, unsigned int device,
125                                struct device *from)
126 {
127         if (!from)
128                 from = all_devices;
129         else
130                 from = from->next;
131         while (from && (from->vendor != vendor || from->device != device)) {
132                 from = from->next;
133         }
134         return from;
135 }
136
137 /**
138  * Find a device of a given class.
139  *
140  * @param class Class of the device.
141  * @param from Pointer to the device structure, used as a starting point
142  *        in the linked list of all_devices, which can be 0 to start at the
143  *        head of the list (i.e. all_devices).
144  * @return Pointer to the device struct.
145  */
146 struct device *dev_find_class(unsigned int class, struct device *from)
147 {
148         if (!from)
149                 from = all_devices;
150         else
151                 from = from->next;
152         while (from && (from->class & 0xffffff00) != class)
153                 from = from->next;
154         return from;
155 }
156
157 /*
158  * Warning: This function uses a static buffer. Don't call it more than once
159  * from the same print statement!
160  */
161 const char *dev_path(device_t dev)
162 {
163         static char buffer[DEVICE_PATH_MAX];
164
165         buffer[0] = '\0';
166         if (!dev) {
167                 memcpy(buffer, "<null>", 7);
168         }
169         else {
170                 switch(dev->path.type) {
171                 case DEVICE_PATH_ROOT:
172                         memcpy(buffer, "Root Device", 12);
173                         break;
174                 case DEVICE_PATH_PCI:
175 #if CONFIG_PCI_BUS_SEGN_BITS
176                         sprintf(buffer, "PCI: %04x:%02x:%02x.%01x",
177                                 dev->bus->secondary>>8, dev->bus->secondary & 0xff,
178                                 PCI_SLOT(dev->path.pci.devfn), PCI_FUNC(dev->path.pci.devfn));
179 #else
180                         sprintf(buffer, "PCI: %02x:%02x.%01x",
181                                 dev->bus->secondary,
182                                 PCI_SLOT(dev->path.pci.devfn), PCI_FUNC(dev->path.pci.devfn));
183 #endif
184                         break;
185                 case DEVICE_PATH_PNP:
186                         sprintf(buffer, "PNP: %04x.%01x",
187                                 dev->path.pnp.port, dev->path.pnp.device);
188                         break;
189                 case DEVICE_PATH_I2C:
190                         sprintf(buffer, "I2C: %02x:%02x",
191                                 dev->bus->secondary,
192                                 dev->path.i2c.device);
193                         break;
194                 case DEVICE_PATH_APIC:
195                         sprintf(buffer, "APIC: %02x",
196                                 dev->path.apic.apic_id);
197                         break;
198                 case DEVICE_PATH_PCI_DOMAIN:
199                         sprintf(buffer, "PCI_DOMAIN: %04x",
200                                 dev->path.pci_domain.domain);
201                         break;
202                 case DEVICE_PATH_APIC_CLUSTER:
203                         sprintf(buffer, "APIC_CLUSTER: %01x",
204                                 dev->path.apic_cluster.cluster);
205                         break;
206                 case DEVICE_PATH_CPU:
207                         sprintf(buffer, "CPU: %02x", dev->path.cpu.id);
208                         break;
209                 case DEVICE_PATH_CPU_BUS:
210                         sprintf(buffer, "CPU_BUS: %02x", dev->path.cpu_bus.id);
211                         break;
212                 default:
213                         printk(BIOS_ERR, "Unknown device path type: %d\n", dev->path.type);
214                         break;
215                 }
216         }
217         return buffer;
218 }
219
220 const char *bus_path(struct bus *bus)
221 {
222         static char buffer[BUS_PATH_MAX];
223         sprintf(buffer, "%s,%d", dev_path(bus->dev), bus->link_num);
224         return buffer;
225 }
226
227 int path_eq(struct device_path *path1, struct device_path *path2)
228 {
229         int equal = 0;
230         if (path1->type == path2->type) {
231                 switch(path1->type) {
232                 case DEVICE_PATH_NONE:
233                         break;
234                 case DEVICE_PATH_ROOT:
235                         equal = 1;
236                         break;
237                 case DEVICE_PATH_PCI:
238                         equal = (path1->pci.devfn == path2->pci.devfn);
239                         break;
240                 case DEVICE_PATH_PNP:
241                         equal = (path1->pnp.port == path2->pnp.port) &&
242                                 (path1->pnp.device == path2->pnp.device);
243                         break;
244                 case DEVICE_PATH_I2C:
245                         equal = (path1->i2c.device == path2->i2c.device);
246                         break;
247                 case DEVICE_PATH_APIC:
248                         equal = (path1->apic.apic_id == path2->apic.apic_id);
249                         break;
250                 case DEVICE_PATH_PCI_DOMAIN:
251                         equal = (path1->pci_domain.domain == path2->pci_domain.domain);
252                         break;
253                 case DEVICE_PATH_APIC_CLUSTER:
254                         equal = (path1->apic_cluster.cluster == path2->apic_cluster.cluster);
255                         break;
256                 case DEVICE_PATH_CPU:
257                         equal = (path1->cpu.id == path2->cpu.id);
258                         break;
259                 case DEVICE_PATH_CPU_BUS:
260                         equal = (path1->cpu_bus.id == path2->cpu_bus.id);
261                         break;
262                 default:
263                         printk(BIOS_ERR, "Uknown device type: %d\n", path1->type);
264                         break;
265                 }
266         }
267         return equal;
268 }
269
270 /**
271  * Allocate 64 more resources to the free list.
272  *
273  * @return TODO.
274  */
275 static int allocate_more_resources(void)
276 {
277         int i;
278         struct resource *new_res_list;
279         new_res_list = malloc(64 * sizeof(*new_res_list));
280
281         if (new_res_list == NULL)
282                 return 0;
283
284         memset(new_res_list, 0, 64 * sizeof(*new_res_list));
285
286         for (i = 0; i < 64-1; i++)
287                 new_res_list[i].next = &new_res_list[i+1];
288
289         free_resources = new_res_list;
290         return 1;
291 }
292
293 /**
294  * Remove resource res from the device's list and add it to the free list.
295  *
296  * @param dev TODO
297  * @param res TODO
298  * @param prev TODO
299  * @return TODO.
300  */
301 static void free_resource(device_t dev, struct resource *res,
302                           struct resource *prev)
303 {
304         if (prev)
305                 prev->next = res->next;
306         else
307                 dev->resource_list = res->next;
308         res->next = free_resources;
309         free_resources = res;
310 }
311
312 /**
313  * See if we have unused but allocated resource structures.
314  * If so remove the allocation.
315  *
316  * @param dev The device to find the resource on.
317  */
318 void compact_resources(device_t dev)
319 {
320         struct resource *res, *next, *prev = NULL;
321         /* Move all of the free resources to the end */
322         for (res = dev->resource_list; res; res = next) {
323                 next = res->next;
324                 if (!res->flags)
325                         free_resource(dev, res, prev);
326                 else
327                         prev = res;
328         }
329 }
330
331 /**
332  * See if a resource structure already exists for a given index.
333  *
334  * @param dev The device to find the resource on.
335  * @param index The index of the resource on the device.
336  * @return The resource, if it already exists.
337  */
338 struct resource *probe_resource(device_t dev, unsigned index)
339 {
340         struct resource *res;
341
342         /* See if there is a resource with the appropriate index */
343         for (res = dev->resource_list; res; res = res->next) {
344                 if (res->index == index)
345                         break;
346         }
347         return res;
348 }
349
350 /**
351  * See if a resource structure already exists for a given index and if not
352  * allocate one.
353  *
354  * Then initialize the initialize the resource to default values.
355  *
356  * @param dev The device to find the resource on.
357  * @param index The index of the resource on the device.
358  * @return TODO.
359  */
360 struct resource *new_resource(device_t dev, unsigned index)
361 {
362         struct resource *resource, *tail;
363
364         /* First move all of the free resources to the end */
365         compact_resources(dev);
366
367         /* See if there is a resource with the appropriate index */
368         resource = probe_resource(dev, index);
369         if (!resource) {
370                 if (free_resources == NULL && !allocate_more_resources())
371                         die("Couldn't allocate more resources.");
372
373                 resource = free_resources;
374                 free_resources = free_resources->next;
375                 memset(resource, 0, sizeof(*resource));
376                 resource->next = NULL;
377                 tail = dev->resource_list;
378                 if (tail) {
379                         while (tail->next) tail = tail->next;
380                         tail->next = resource;
381                 }
382                 else
383                         dev->resource_list = resource;
384         }
385         /* Initialize the resource values */
386         if (!(resource->flags & IORESOURCE_FIXED)) {
387                 resource->flags = 0;
388                 resource->base = 0;
389         }
390         resource->size  = 0;
391         resource->limit = 0;
392         resource->index = index;
393         resource->align = 0;
394         resource->gran  = 0;
395
396         return resource;
397 }
398
399 /**
400  * Return an existing resource structure for a given index.
401  *
402  * @param dev The device to find the resource on.
403  * @param index The index of the resource on the device.
404  * return TODO.
405  */
406 struct resource *find_resource(device_t dev, unsigned index)
407 {
408         struct resource *resource;
409
410         /* See if there is a resource with the appropriate index */
411         resource = probe_resource(dev, index);
412         if (!resource) {
413                 printk(BIOS_EMERG, "%s missing resource: %02x\n",
414                         dev_path(dev), index);
415                 die("");
416         }
417         return resource;
418 }
419
420
421 /**
422  * Round a number up to the next multiple of gran.
423  *
424  * @param val The starting value.
425  * @param gran Granularity we are aligning the number to.
426  * @return The aligned value.
427  */
428 static resource_t align_up(resource_t val, unsigned long gran)
429 {
430         resource_t mask;
431         mask = (1ULL << gran) - 1ULL;
432         val += mask;
433         val &= ~mask;
434         return val;
435 }
436
437 /**
438  * Round a number up to the previous multiple of gran.
439  *
440  * @param val The starting value.
441  * @param gran Granularity we are aligning the number to.
442  * @return The aligned value.
443  */
444 static resource_t align_down(resource_t val, unsigned long gran)
445 {
446         resource_t mask;
447         mask = (1ULL << gran) - 1ULL;
448         val &= ~mask;
449         return val;
450 }
451
452 /**
453  * Compute the maximum address that is part of a resource.
454  *
455  * @param resource The resource whose limit is desired.
456  * @return The end.
457  */
458 resource_t resource_end(struct resource *resource)
459 {
460         resource_t base, end;
461         /* get the base address */
462         base = resource->base;
463
464         /* For a non bridge resource granularity and alignment are the same.
465          * For a bridge resource align is the largest needed alignment below
466          * the bridge.  While the granularity is simply how many low bits of the
467          * address cannot be set.
468          */
469
470         /* Get the end (rounded up) */
471         end = base + align_up(resource->size, resource->gran) - 1;
472
473         return end;
474 }
475
476 /**
477  * Compute the maximum legal value for resource->base.
478  *
479  * @param resource The resource whose maximum is desired.
480  * @return The maximum.
481  */
482 resource_t resource_max(struct resource *resource)
483 {
484         resource_t max;
485
486         max = align_down(resource->limit - resource->size + 1, resource->align);
487
488         return max;
489 }
490
491 /**
492  * Return the resource type of a resource.
493  *
494  * @param resource The resource type to decode.
495  * @return TODO.
496  */
497 const char *resource_type(struct resource *resource)
498 {
499         static char buffer[RESOURCE_TYPE_MAX];
500         sprintf(buffer, "%s%s%s%s",
501                 ((resource->flags & IORESOURCE_READONLY)? "ro": ""),
502                 ((resource->flags & IORESOURCE_PREFETCH)? "pref":""),
503                 ((resource->flags == 0)? "unused":
504                 (resource->flags & IORESOURCE_IO)? "io":
505                 (resource->flags & IORESOURCE_DRQ)? "drq":
506                 (resource->flags & IORESOURCE_IRQ)? "irq":
507                 (resource->flags & IORESOURCE_MEM)? "mem":"??????"),
508                 ((resource->flags & IORESOURCE_PCI64)?"64":""));
509         return buffer;
510 }
511
512 /**
513  * Print the resource that was just stored.
514  *
515  * @param dev The device the stored resorce lives on.
516  * @param resource The resource that was just stored.
517  * @param comment TODO
518  */
519 void report_resource_stored(device_t dev, struct resource *resource,
520                             const char *comment)
521 {
522         if (resource->flags & IORESOURCE_STORED) {
523                 char buf[10];
524                 unsigned long long base, end;
525                 base = resource->base;
526                 end = resource_end(resource);
527                 buf[0] = '\0';
528                 if (resource->flags & IORESOURCE_PCI_BRIDGE) {
529 #if CONFIG_PCI_BUS_SEGN_BITS
530                         sprintf(buf, "bus %04x:%02x ", dev->bus->secondary>>8, dev->link_list->secondary & 0xff);
531 #else
532                         sprintf(buf, "bus %02x ", dev->link_list->secondary);
533 #endif
534                 }
535                 printk(BIOS_DEBUG,
536                         "%s %02lx <- [0x%010Lx - 0x%010Lx] size 0x%08Lx gran 0x%02x %s%s%s\n",
537                         dev_path(dev),
538                         resource->index,
539                         base, end,
540                         resource->size, resource->gran,
541                         buf,
542                         resource_type(resource),
543                         comment);
544         }
545 }
546
547 void search_bus_resources(struct bus *bus,
548         unsigned long type_mask, unsigned long type,
549         resource_search_t search, void *gp)
550 {
551         struct device *curdev;
552         for (curdev = bus->children; curdev; curdev = curdev->sibling) {
553                 struct resource *res;
554                 /* Ignore disabled devices */
555                 if (!curdev->enabled) continue;
556                 for (res = curdev->resource_list; res; res = res->next) {
557                         /* If it isn't the right kind of resource ignore it */
558                         if ((res->flags & type_mask) != type) {
559                                 continue;
560                         }
561                         /* If it is a subtractive resource recurse */
562                         if (res->flags & IORESOURCE_SUBTRACTIVE) {
563                                 struct bus * subbus;
564                                 for (subbus = curdev->link_list; subbus; subbus = subbus->next)
565                                         if (subbus->link_num == IOINDEX_SUBTRACTIVE_LINK(res->index))
566                                                 break;
567                                 search_bus_resources(subbus, type_mask, type, search, gp);
568                                 continue;
569                         }
570                         search(gp, curdev, res);
571                 }
572         }
573 }
574
575 void search_global_resources(
576         unsigned long type_mask, unsigned long type,
577         resource_search_t search, void *gp)
578 {
579         struct device *curdev;
580         for (curdev = all_devices; curdev; curdev = curdev->next) {
581                 struct resource *res;
582                 /* Ignore disabled devices */
583                 if (!curdev->enabled) continue;
584                 for (res = curdev->resource_list; res; res = res->next) {
585                         /* If it isn't the right kind of resource ignore it */
586                         if ((res->flags & type_mask) != type) {
587                                 continue;
588                         }
589                         /* If it is a subtractive resource ignore it */
590                         if (res->flags & IORESOURCE_SUBTRACTIVE) {
591                                 continue;
592                         }
593                         search(gp, curdev, res);
594                 }
595         }
596 }
597
598 void dev_set_enabled(device_t dev, int enable)
599 {
600         if (dev->enabled == enable) {
601                 return;
602         }
603         dev->enabled = enable;
604         if (dev->ops && dev->ops->enable) {
605                 dev->ops->enable(dev);
606         }
607         else if (dev->chip_ops && dev->chip_ops->enable_dev) {
608                 dev->chip_ops->enable_dev(dev);
609         }
610 }
611
612 void disable_children(struct bus *bus)
613 {
614         device_t child;
615         for (child = bus->children; child; child = child->sibling) {
616                 struct bus *link;
617                 for (link = child->link_list; link; link = link->next) {
618                         disable_children(link);
619                 }
620                 dev_set_enabled(child, 0);
621         }
622 }
623
624 static void resource_tree(struct device *root, int debug_level, int depth)
625 {
626         int i = 0;
627         struct device *child;
628         struct bus *link;
629         struct resource *res;
630         char indent[30];        /* If your tree has more levels, it's wrong. */
631
632         for (i = 0; i < depth + 1 && i < 29; i++)
633                 indent[i] = ' ';
634         indent[i] = '\0';
635
636         do_printk(BIOS_DEBUG, "%s%s", indent, dev_path(root));
637         if (root->link_list && root->link_list->children)
638                 do_printk(BIOS_DEBUG, " child on link 0 %s",
639                           dev_path(root->link_list->children));
640         do_printk(BIOS_DEBUG, "\n");
641
642         for (res = root->resource_list; res; res = res->next) {
643                 do_printk(debug_level,
644                           "%s%s resource base %llx size %llx align %d gran %d limit %llx flags %lx index %lx\n",
645                           indent, dev_path(root), res->base,
646                           res->size, res->align,
647                           res->gran, res->limit,
648                           res->flags, res->index);
649         }
650
651         for (link = root->link_list; link; link = link->next) {
652                 for (child = link->children; child; child = child->sibling)
653                         resource_tree(child, debug_level, depth + 1);
654         }
655 }
656
657 void print_resource_tree(struct device * root, int debug_level,
658                          const char *msg)
659 {
660         /* Bail if root is null. */
661         if (!root) {
662                 do_printk(debug_level, "%s passed NULL for root!\n", __func__);
663                 return;
664         }
665
666         /* Bail if not printing to screen. */
667         if (!do_printk(debug_level, "Show resources in subtree (%s)...%s\n",
668                     dev_path(root), msg))
669                 return;
670         resource_tree(root, debug_level, 0);
671 }
672
673 void show_devs_tree(struct device *dev, int debug_level, int depth, int linknum)
674 {
675         char depth_str[20] = "";
676         int i;
677         struct device *sibling;
678         struct bus *link;
679
680         for (i = 0; i < depth; i++)
681                 depth_str[i] = ' ';
682         depth_str[i] = '\0';
683         do_printk(debug_level, "%s%s: enabled %d\n",
684                   depth_str, dev_path(dev), dev->enabled);
685         for (link = dev->link_list; link; link = link->next) {
686                 for (sibling = link->children; sibling;
687                      sibling = sibling->sibling)
688                         show_devs_tree(sibling, debug_level, depth + 1, i);
689         }
690 }
691
692 void show_all_devs_tree(int debug_level, const char *msg)
693 {
694         /* Bail if not printing to screen. */
695         if (!do_printk(debug_level, "Show all devs in tree form...%s\n", msg))
696                 return;
697         show_devs_tree(all_devices, debug_level, 0, -1);
698 }
699
700 void show_devs_subtree(struct device *root, int debug_level, const char *msg)
701 {
702         /* Bail if not printing to screen. */
703         if (!do_printk(debug_level, "Show all devs in subtree %s...%s\n",
704                     dev_path(root), msg))
705                 return;
706         do_printk(debug_level, "%s\n", msg);
707         show_devs_tree(root, debug_level, 0, -1);
708 }
709
710 void show_all_devs(int debug_level, const char *msg)
711 {
712         struct device *dev;
713
714         /* Bail if not printing to screen. */
715         if (!do_printk(debug_level, "Show all devs...%s\n", msg))
716                 return;
717         for (dev = all_devices; dev; dev = dev->next) {
718                 do_printk(debug_level, "%s: enabled %d\n",
719                           dev_path(dev), dev->enabled);
720         }
721 }
722
723 void show_one_resource(int debug_level, struct device *dev,
724                        struct resource *resource, const char *comment)
725 {
726         char buf[10];
727         unsigned long long base, end;
728         base = resource->base;
729         end = resource_end(resource);
730         buf[0] = '\0';
731 /*
732         if (resource->flags & IORESOURCE_BRIDGE) {
733 #if CONFIG_PCI_BUS_SEGN_BITS
734                 sprintf(buf, "bus %04x:%02x ", dev->bus->secondary >> 8,
735                         dev->link[0].secondary & 0xff);
736 #else
737                 sprintf(buf, "bus %02x ", dev->link[0].secondary);
738 #endif
739         }
740 */
741         do_printk(debug_level, "%s %02lx <- [0x%010llx - 0x%010llx] "
742                   "size 0x%08Lx gran 0x%02x %s%s%s\n",
743                   dev_path(dev), resource->index, base, end,
744                   resource->size, resource->gran, buf,
745                   resource_type(resource), comment);
746
747 }
748
749 void show_all_devs_resources(int debug_level, const char* msg)
750 {
751         struct device *dev;
752
753         if(!do_printk(debug_level, "Show all devs with resources...%s\n", msg))
754                 return;
755
756         for (dev = all_devices; dev; dev = dev->next) {
757                 struct resource *res;
758                 do_printk(debug_level, "%s: enabled %d\n",
759                           dev_path(dev), dev->enabled);
760                 for (res = dev->resource_list; res; res = res->next)
761                         show_one_resource(debug_level, dev, res, "");
762         }
763 }
764
765 void ram_resource(device_t dev, unsigned long index,
766                   unsigned long basek, unsigned long sizek)
767 {
768         struct resource *resource;
769
770         if (!sizek)
771                 return;
772
773         resource = new_resource(dev, index);
774         resource->base = ((resource_t)basek) << 10;
775         resource->size = ((resource_t)sizek) << 10;
776         resource->flags = IORESOURCE_MEM | IORESOURCE_CACHEABLE | \
777                 IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
778 }
779
780 void tolm_test(void *gp, struct device *dev, struct resource *new)
781 {
782         struct resource **best_p = gp;
783         struct resource *best;
784
785         best = *best_p;
786
787         if (!best || (best->base > new->base))
788                 best = new;
789
790         *best_p = best;
791 }
792
793 u32 find_pci_tolm(struct bus *bus)
794 {
795         struct resource *min = NULL;
796         u32 tolm;
797
798         search_bus_resources(bus, IORESOURCE_MEM, IORESOURCE_MEM,
799                              tolm_test, &min);
800
801         tolm = 0xffffffffUL;
802
803         if (min && tolm > min->base)
804                 tolm = min->base;
805
806         return tolm;
807 }