hotplug.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #include <linux/kernel.h>
  2. #include <linux/pci.h>
  3. #include <linux/module.h>
  4. #include "pci.h"
  5. int pci_hotplug (struct device *dev, char **envp, int num_envp,
  6. char *buffer, int buffer_size)
  7. {
  8. struct pci_dev *pdev;
  9. char *scratch;
  10. int i = 0;
  11. int length = 0;
  12. if (!dev)
  13. return -ENODEV;
  14. pdev = to_pci_dev(dev);
  15. if (!pdev)
  16. return -ENODEV;
  17. scratch = buffer;
  18. /* stuff we want to pass to /sbin/hotplug */
  19. envp[i++] = scratch;
  20. length += scnprintf (scratch, buffer_size - length, "PCI_CLASS=%04X",
  21. pdev->class);
  22. if ((buffer_size - length <= 0) || (i >= num_envp))
  23. return -ENOMEM;
  24. ++length;
  25. scratch += length;
  26. envp[i++] = scratch;
  27. length += scnprintf (scratch, buffer_size - length, "PCI_ID=%04X:%04X",
  28. pdev->vendor, pdev->device);
  29. if ((buffer_size - length <= 0) || (i >= num_envp))
  30. return -ENOMEM;
  31. ++length;
  32. scratch += length;
  33. envp[i++] = scratch;
  34. length += scnprintf (scratch, buffer_size - length,
  35. "PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor,
  36. pdev->subsystem_device);
  37. if ((buffer_size - length <= 0) || (i >= num_envp))
  38. return -ENOMEM;
  39. ++length;
  40. scratch += length;
  41. envp[i++] = scratch;
  42. length += scnprintf (scratch, buffer_size - length, "PCI_SLOT_NAME=%s",
  43. pci_name(pdev));
  44. if ((buffer_size - length <= 0) || (i >= num_envp))
  45. return -ENOMEM;
  46. envp[i] = NULL;
  47. return 0;
  48. }
  49. static int pci_visit_bus (struct pci_visit * fn, struct pci_bus_wrapped *wrapped_bus, struct pci_dev_wrapped *wrapped_parent)
  50. {
  51. struct list_head *ln;
  52. struct pci_dev *dev;
  53. struct pci_dev_wrapped wrapped_dev;
  54. int result = 0;
  55. pr_debug("PCI: Scanning bus %04x:%02x\n", pci_domain_nr(wrapped_bus->bus),
  56. wrapped_bus->bus->number);
  57. if (fn->pre_visit_pci_bus) {
  58. result = fn->pre_visit_pci_bus(wrapped_bus, wrapped_parent);
  59. if (result)
  60. return result;
  61. }
  62. ln = wrapped_bus->bus->devices.next;
  63. while (ln != &wrapped_bus->bus->devices) {
  64. dev = pci_dev_b(ln);
  65. ln = ln->next;
  66. memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped));
  67. wrapped_dev.dev = dev;
  68. result = pci_visit_dev(fn, &wrapped_dev, wrapped_bus);
  69. if (result)
  70. return result;
  71. }
  72. if (fn->post_visit_pci_bus)
  73. result = fn->post_visit_pci_bus(wrapped_bus, wrapped_parent);
  74. return result;
  75. }
  76. static int pci_visit_bridge (struct pci_visit * fn,
  77. struct pci_dev_wrapped *wrapped_dev,
  78. struct pci_bus_wrapped *wrapped_parent)
  79. {
  80. struct pci_bus *bus;
  81. struct pci_bus_wrapped wrapped_bus;
  82. int result = 0;
  83. pr_debug("PCI: Scanning bridge %s\n", pci_name(wrapped_dev->dev));
  84. if (fn->visit_pci_dev) {
  85. result = fn->visit_pci_dev(wrapped_dev, wrapped_parent);
  86. if (result)
  87. return result;
  88. }
  89. bus = wrapped_dev->dev->subordinate;
  90. if (bus) {
  91. memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped));
  92. wrapped_bus.bus = bus;
  93. result = pci_visit_bus(fn, &wrapped_bus, wrapped_dev);
  94. }
  95. return result;
  96. }
  97. /**
  98. * pci_visit_dev - scans the pci buses.
  99. * @fn: callback functions that are called while visiting
  100. * @wrapped_dev: the device to scan
  101. * @wrapped_parent: the bus where @wrapped_dev is connected to
  102. *
  103. * Every bus and every function is presented to a custom
  104. * function that can act upon it.
  105. */
  106. int pci_visit_dev(struct pci_visit *fn, struct pci_dev_wrapped *wrapped_dev,
  107. struct pci_bus_wrapped *wrapped_parent)
  108. {
  109. struct pci_dev* dev = wrapped_dev ? wrapped_dev->dev : NULL;
  110. int result = 0;
  111. if (!dev)
  112. return 0;
  113. if (fn->pre_visit_pci_dev) {
  114. result = fn->pre_visit_pci_dev(wrapped_dev, wrapped_parent);
  115. if (result)
  116. return result;
  117. }
  118. switch (dev->class >> 8) {
  119. case PCI_CLASS_BRIDGE_PCI:
  120. result = pci_visit_bridge(fn, wrapped_dev,
  121. wrapped_parent);
  122. if (result)
  123. return result;
  124. break;
  125. default:
  126. pr_debug("PCI: Scanning device %s\n", pci_name(dev));
  127. if (fn->visit_pci_dev) {
  128. result = fn->visit_pci_dev (wrapped_dev,
  129. wrapped_parent);
  130. if (result)
  131. return result;
  132. }
  133. }
  134. if (fn->post_visit_pci_dev)
  135. result = fn->post_visit_pci_dev(wrapped_dev, wrapped_parent);
  136. return result;
  137. }
  138. EXPORT_SYMBOL(pci_visit_dev);