bus_numa.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #include <linux/init.h>
  2. #include <linux/pci.h>
  3. #include <linux/range.h>
  4. #include "bus_numa.h"
  5. int pci_root_num;
  6. struct pci_root_info pci_root_info[PCI_ROOT_NR];
  7. void x86_pci_root_bus_resources(int bus, struct list_head *resources)
  8. {
  9. int i;
  10. int j;
  11. struct pci_root_info *info;
  12. if (!pci_root_num)
  13. goto default_resources;
  14. for (i = 0; i < pci_root_num; i++) {
  15. if (pci_root_info[i].bus_min == bus)
  16. break;
  17. }
  18. if (i == pci_root_num)
  19. goto default_resources;
  20. printk(KERN_DEBUG "PCI: root bus %02x: hardware-probed resources\n",
  21. bus);
  22. info = &pci_root_info[i];
  23. for (j = 0; j < info->res_num; j++) {
  24. struct resource *res;
  25. struct resource *root;
  26. res = &info->res[j];
  27. pci_add_resource(resources, res);
  28. if (res->flags & IORESOURCE_IO)
  29. root = &ioport_resource;
  30. else
  31. root = &iomem_resource;
  32. insert_resource(root, res);
  33. }
  34. return;
  35. default_resources:
  36. /*
  37. * We don't have any host bridge aperture information from the
  38. * "native host bridge drivers," e.g., amd_bus or broadcom_bus,
  39. * so fall back to the defaults historically used by pci_create_bus().
  40. */
  41. printk(KERN_DEBUG "PCI: root bus %02x: using default resources\n", bus);
  42. pci_add_resource(resources, &ioport_resource);
  43. pci_add_resource(resources, &iomem_resource);
  44. }
  45. void __devinit update_res(struct pci_root_info *info, resource_size_t start,
  46. resource_size_t end, unsigned long flags, int merge)
  47. {
  48. int i;
  49. struct resource *res;
  50. if (start > end)
  51. return;
  52. if (start == MAX_RESOURCE)
  53. return;
  54. if (!merge)
  55. goto addit;
  56. /* try to merge it with old one */
  57. for (i = 0; i < info->res_num; i++) {
  58. resource_size_t final_start, final_end;
  59. resource_size_t common_start, common_end;
  60. res = &info->res[i];
  61. if (res->flags != flags)
  62. continue;
  63. common_start = max(res->start, start);
  64. common_end = min(res->end, end);
  65. if (common_start > common_end + 1)
  66. continue;
  67. final_start = min(res->start, start);
  68. final_end = max(res->end, end);
  69. res->start = final_start;
  70. res->end = final_end;
  71. return;
  72. }
  73. addit:
  74. /* need to add that */
  75. if (info->res_num >= RES_NUM)
  76. return;
  77. res = &info->res[info->res_num];
  78. res->name = info->name;
  79. res->flags = flags;
  80. res->start = start;
  81. res->end = end;
  82. res->child = NULL;
  83. info->res_num++;
  84. }