bus_numa.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #include <linux/init.h>
  2. #include <linux/pci.h>
  3. #include "bus_numa.h"
  4. int pci_root_num;
  5. struct pci_root_info pci_root_info[PCI_ROOT_NR];
  6. void x86_pci_root_bus_res_quirks(struct pci_bus *b)
  7. {
  8. int i;
  9. int j;
  10. struct pci_root_info *info;
  11. /* don't go for it if _CRS is used already */
  12. if (b->resource[0] != &ioport_resource ||
  13. b->resource[1] != &iomem_resource)
  14. return;
  15. if (!pci_root_num)
  16. return;
  17. for (i = 0; i < pci_root_num; i++) {
  18. if (pci_root_info[i].bus_min == b->number)
  19. break;
  20. }
  21. if (i == pci_root_num)
  22. return;
  23. printk(KERN_DEBUG "PCI: peer root bus %02x res updated from pci conf\n",
  24. b->number);
  25. info = &pci_root_info[i];
  26. for (j = 0; j < info->res_num; j++) {
  27. struct resource *res;
  28. struct resource *root;
  29. res = &info->res[j];
  30. b->resource[j] = res;
  31. if (res->flags & IORESOURCE_IO)
  32. root = &ioport_resource;
  33. else
  34. root = &iomem_resource;
  35. insert_resource(root, res);
  36. }
  37. }
  38. void __devinit update_res(struct pci_root_info *info, resource_size_t start,
  39. resource_size_t end, unsigned long flags, int merge)
  40. {
  41. int i;
  42. struct resource *res;
  43. if (start > end)
  44. return;
  45. if (!merge)
  46. goto addit;
  47. /* try to merge it with old one */
  48. for (i = 0; i < info->res_num; i++) {
  49. resource_size_t final_start, final_end;
  50. resource_size_t common_start, common_end;
  51. res = &info->res[i];
  52. if (res->flags != flags)
  53. continue;
  54. common_start = max(res->start, start);
  55. common_end = min(res->end, end);
  56. if (common_start > common_end + 1)
  57. continue;
  58. final_start = min(res->start, start);
  59. final_end = max(res->end, end);
  60. res->start = final_start;
  61. res->end = final_end;
  62. return;
  63. }
  64. addit:
  65. /* need to add that */
  66. if (info->res_num >= RES_NUM)
  67. return;
  68. res = &info->res[info->res_num];
  69. res->name = info->name;
  70. res->flags = flags;
  71. res->start = start;
  72. res->end = end;
  73. res->child = NULL;
  74. info->res_num++;
  75. }