pci_slot.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * pci_slot.c - ACPI PCI Slot Driver
  4. *
  5. * The code here is heavily leveraged from the acpiphp module.
  6. * Thanks to Matthew Wilcox <matthew@wil.cx> for much guidance.
  7. * Thanks to Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> for code
  8. * review and fixes.
  9. *
  10. * Copyright (C) 2007-2008 Hewlett-Packard Development Company, L.P.
  11. * Alex Chiang <achiang@hp.com>
  12. *
  13. * Copyright (C) 2013 Huawei Tech. Co., Ltd.
  14. * Jiang Liu <jiang.liu@huawei.com>
  15. */
  16. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  17. #include <linux/kernel.h>
  18. #include <linux/init.h>
  19. #include <linux/slab.h>
  20. #include <linux/types.h>
  21. #include <linux/list.h>
  22. #include <linux/pci.h>
  23. #include <linux/acpi.h>
  24. #include <linux/dmi.h>
  25. #include <linux/pci-acpi.h>
  26. static int check_sta_before_sun;
  27. #define SLOT_NAME_SIZE 21 /* Inspired by #define in acpiphp.h */
  28. struct acpi_pci_slot {
  29. struct pci_slot *pci_slot; /* corresponding pci_slot */
  30. struct list_head list; /* node in the list of slots */
  31. };
  32. static LIST_HEAD(slot_list);
  33. static DEFINE_MUTEX(slot_list_lock);
  34. static int
  35. check_slot(acpi_handle handle, unsigned long long *sun)
  36. {
  37. int device = -1;
  38. unsigned long long adr, sta;
  39. acpi_status status;
  40. struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
  41. acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
  42. pr_debug("Checking slot on path: %s\n", (char *)buffer.pointer);
  43. if (check_sta_before_sun) {
  44. /* If SxFy doesn't have _STA, we just assume it's there */
  45. status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
  46. if (ACPI_SUCCESS(status) && !(sta & ACPI_STA_DEVICE_PRESENT))
  47. goto out;
  48. }
  49. status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr);
  50. if (ACPI_FAILURE(status)) {
  51. pr_debug("_ADR returned %d on %s\n",
  52. status, (char *)buffer.pointer);
  53. goto out;
  54. }
  55. /* No _SUN == not a slot == bail */
  56. status = acpi_evaluate_integer(handle, "_SUN", NULL, sun);
  57. if (ACPI_FAILURE(status)) {
  58. pr_debug("_SUN returned %d on %s\n",
  59. status, (char *)buffer.pointer);
  60. goto out;
  61. }
  62. device = (adr >> 16) & 0xffff;
  63. out:
  64. kfree(buffer.pointer);
  65. return device;
  66. }
  67. /*
  68. * Check whether handle has an associated slot and create PCI slot if it has.
  69. */
  70. static acpi_status
  71. register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
  72. {
  73. int device;
  74. unsigned long long sun;
  75. char name[SLOT_NAME_SIZE];
  76. struct acpi_pci_slot *slot;
  77. struct pci_slot *pci_slot;
  78. struct pci_bus *pci_bus = context;
  79. device = check_slot(handle, &sun);
  80. if (device < 0)
  81. return AE_OK;
  82. /*
  83. * There may be multiple PCI functions associated with the same slot.
  84. * Check whether PCI slot has already been created for this PCI device.
  85. */
  86. list_for_each_entry(slot, &slot_list, list) {
  87. pci_slot = slot->pci_slot;
  88. if (pci_slot->bus == pci_bus && pci_slot->number == device)
  89. return AE_OK;
  90. }
  91. slot = kmalloc(sizeof(*slot), GFP_KERNEL);
  92. if (!slot)
  93. return AE_OK;
  94. snprintf(name, sizeof(name), "%llu", sun);
  95. pci_slot = pci_create_slot(pci_bus, device, name, NULL);
  96. if (IS_ERR(pci_slot)) {
  97. pr_err("pci_create_slot returned %ld\n", PTR_ERR(pci_slot));
  98. kfree(slot);
  99. return AE_OK;
  100. }
  101. slot->pci_slot = pci_slot;
  102. list_add(&slot->list, &slot_list);
  103. get_device(&pci_bus->dev);
  104. pr_debug("%p, pci_bus: %x, device: %d, name: %s\n",
  105. pci_slot, pci_bus->number, device, name);
  106. return AE_OK;
  107. }
  108. void acpi_pci_slot_enumerate(struct pci_bus *bus)
  109. {
  110. acpi_handle handle = ACPI_HANDLE(bus->bridge);
  111. if (handle) {
  112. mutex_lock(&slot_list_lock);
  113. acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
  114. register_slot, NULL, bus, NULL);
  115. mutex_unlock(&slot_list_lock);
  116. }
  117. }
  118. void acpi_pci_slot_remove(struct pci_bus *bus)
  119. {
  120. struct acpi_pci_slot *slot, *tmp;
  121. mutex_lock(&slot_list_lock);
  122. list_for_each_entry_safe(slot, tmp, &slot_list, list) {
  123. if (slot->pci_slot->bus == bus) {
  124. list_del(&slot->list);
  125. pci_destroy_slot(slot->pci_slot);
  126. put_device(&bus->dev);
  127. kfree(slot);
  128. }
  129. }
  130. mutex_unlock(&slot_list_lock);
  131. }
  132. static int do_sta_before_sun(const struct dmi_system_id *d)
  133. {
  134. pr_info("%s detected: will evaluate _STA before calling _SUN\n",
  135. d->ident);
  136. check_sta_before_sun = 1;
  137. return 0;
  138. }
  139. static const struct dmi_system_id acpi_pci_slot_dmi_table[] __initconst = {
  140. /*
  141. * Fujitsu Primequest machines will return 1023 to indicate an
  142. * error if the _SUN method is evaluated on SxFy objects that
  143. * are not present (as indicated by _STA), so for those machines,
  144. * we want to check _STA before evaluating _SUN.
  145. */
  146. {
  147. .callback = do_sta_before_sun,
  148. .ident = "Fujitsu PRIMEQUEST",
  149. .matches = {
  150. DMI_MATCH(DMI_BIOS_VENDOR, "FUJITSU LIMITED"),
  151. DMI_MATCH(DMI_BIOS_VERSION, "PRIMEQUEST"),
  152. },
  153. },
  154. {}
  155. };
  156. void __init acpi_pci_slot_init(void)
  157. {
  158. dmi_check_system(acpi_pci_slot_dmi_table);
  159. }