aerdrv.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. /*
  2. * drivers/pci/pcie/aer/aerdrv.c
  3. *
  4. * This file is subject to the terms and conditions of the GNU General Public
  5. * License. See the file "COPYING" in the main directory of this archive
  6. * for more details.
  7. *
  8. * This file implements the AER root port service driver. The driver will
  9. * register an irq handler. When root port triggers an AER interrupt, the irq
  10. * handler will collect root port status and schedule a work.
  11. *
  12. * Copyright (C) 2006 Intel Corp.
  13. * Tom Long Nguyen (tom.l.nguyen@intel.com)
  14. * Zhang Yanmin (yanmin.zhang@intel.com)
  15. *
  16. */
  17. #include <linux/pci.h>
  18. #include <linux/pci-acpi.h>
  19. #include <linux/sched.h>
  20. #include <linux/kernel.h>
  21. #include <linux/errno.h>
  22. #include <linux/pm.h>
  23. #include <linux/init.h>
  24. #include <linux/interrupt.h>
  25. #include <linux/delay.h>
  26. #include <linux/pcieport_if.h>
  27. #include <linux/slab.h>
  28. #include "aerdrv.h"
  29. #include "../../pci.h"
  30. static int aer_probe(struct pcie_device *dev);
  31. static void aer_remove(struct pcie_device *dev);
  32. static pci_ers_result_t aer_error_detected(struct pci_dev *dev,
  33. enum pci_channel_state error);
  34. static void aer_error_resume(struct pci_dev *dev);
  35. static pci_ers_result_t aer_root_reset(struct pci_dev *dev);
  36. static const struct pci_error_handlers aer_error_handlers = {
  37. .error_detected = aer_error_detected,
  38. .resume = aer_error_resume,
  39. };
  40. static struct pcie_port_service_driver aerdriver = {
  41. .name = "aer",
  42. .port_type = PCI_EXP_TYPE_ROOT_PORT,
  43. .service = PCIE_PORT_SERVICE_AER,
  44. .probe = aer_probe,
  45. .remove = aer_remove,
  46. .err_handler = &aer_error_handlers,
  47. .reset_link = aer_root_reset,
  48. };
  49. static int pcie_aer_disable;
  50. void pci_no_aer(void)
  51. {
  52. pcie_aer_disable = 1;
  53. }
  54. bool pci_aer_available(void)
  55. {
  56. return !pcie_aer_disable && pci_msi_enabled();
  57. }
  58. static int set_device_error_reporting(struct pci_dev *dev, void *data)
  59. {
  60. bool enable = *((bool *)data);
  61. int type = pci_pcie_type(dev);
  62. if ((type == PCI_EXP_TYPE_ROOT_PORT) ||
  63. (type == PCI_EXP_TYPE_UPSTREAM) ||
  64. (type == PCI_EXP_TYPE_DOWNSTREAM)) {
  65. if (enable)
  66. pci_enable_pcie_error_reporting(dev);
  67. else
  68. pci_disable_pcie_error_reporting(dev);
  69. }
  70. if (enable)
  71. pcie_set_ecrc_checking(dev);
  72. return 0;
  73. }
  74. /**
  75. * set_downstream_devices_error_reporting - enable/disable the error reporting bits on the root port and its downstream ports.
  76. * @dev: pointer to root port's pci_dev data structure
  77. * @enable: true = enable error reporting, false = disable error reporting.
  78. */
  79. static void set_downstream_devices_error_reporting(struct pci_dev *dev,
  80. bool enable)
  81. {
  82. set_device_error_reporting(dev, &enable);
  83. if (!dev->subordinate)
  84. return;
  85. pci_walk_bus(dev->subordinate, set_device_error_reporting, &enable);
  86. }
  87. /**
  88. * aer_enable_rootport - enable Root Port's interrupts when receiving messages
  89. * @rpc: pointer to a Root Port data structure
  90. *
  91. * Invoked when PCIe bus loads AER service driver.
  92. */
  93. static void aer_enable_rootport(struct aer_rpc *rpc)
  94. {
  95. struct pci_dev *pdev = rpc->rpd->port;
  96. int aer_pos;
  97. u16 reg16;
  98. u32 reg32;
  99. /* Clear PCIe Capability's Device Status */
  100. pcie_capability_read_word(pdev, PCI_EXP_DEVSTA, &reg16);
  101. pcie_capability_write_word(pdev, PCI_EXP_DEVSTA, reg16);
  102. /* Disable system error generation in response to error messages */
  103. pcie_capability_clear_word(pdev, PCI_EXP_RTCTL,
  104. SYSTEM_ERROR_INTR_ON_MESG_MASK);
  105. aer_pos = pdev->aer_cap;
  106. /* Clear error status */
  107. pci_read_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, &reg32);
  108. pci_write_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, reg32);
  109. pci_read_config_dword(pdev, aer_pos + PCI_ERR_COR_STATUS, &reg32);
  110. pci_write_config_dword(pdev, aer_pos + PCI_ERR_COR_STATUS, reg32);
  111. pci_read_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, &reg32);
  112. pci_write_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, reg32);
  113. /*
  114. * Enable error reporting for the root port device and downstream port
  115. * devices.
  116. */
  117. set_downstream_devices_error_reporting(pdev, true);
  118. /* Enable Root Port's interrupt in response to error messages */
  119. pci_read_config_dword(pdev, aer_pos + PCI_ERR_ROOT_COMMAND, &reg32);
  120. reg32 |= ROOT_PORT_INTR_ON_MESG_MASK;
  121. pci_write_config_dword(pdev, aer_pos + PCI_ERR_ROOT_COMMAND, reg32);
  122. }
  123. /**
  124. * aer_disable_rootport - disable Root Port's interrupts when receiving messages
  125. * @rpc: pointer to a Root Port data structure
  126. *
  127. * Invoked when PCIe bus unloads AER service driver.
  128. */
  129. static void aer_disable_rootport(struct aer_rpc *rpc)
  130. {
  131. struct pci_dev *pdev = rpc->rpd->port;
  132. u32 reg32;
  133. int pos;
  134. /*
  135. * Disable error reporting for the root port device and downstream port
  136. * devices.
  137. */
  138. set_downstream_devices_error_reporting(pdev, false);
  139. pos = pdev->aer_cap;
  140. /* Disable Root's interrupt in response to error messages */
  141. pci_read_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, &reg32);
  142. reg32 &= ~ROOT_PORT_INTR_ON_MESG_MASK;
  143. pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, reg32);
  144. /* Clear Root's error status reg */
  145. pci_read_config_dword(pdev, pos + PCI_ERR_ROOT_STATUS, &reg32);
  146. pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_STATUS, reg32);
  147. }
  148. /**
  149. * aer_irq - Root Port's ISR
  150. * @irq: IRQ assigned to Root Port
  151. * @context: pointer to Root Port data structure
  152. *
  153. * Invoked when Root Port detects AER messages.
  154. */
  155. irqreturn_t aer_irq(int irq, void *context)
  156. {
  157. unsigned int status, id;
  158. struct pcie_device *pdev = (struct pcie_device *)context;
  159. struct aer_rpc *rpc = get_service_data(pdev);
  160. int next_prod_idx;
  161. unsigned long flags;
  162. int pos;
  163. pos = pdev->port->aer_cap;
  164. /*
  165. * Must lock access to Root Error Status Reg, Root Error ID Reg,
  166. * and Root error producer/consumer index
  167. */
  168. spin_lock_irqsave(&rpc->e_lock, flags);
  169. /* Read error status */
  170. pci_read_config_dword(pdev->port, pos + PCI_ERR_ROOT_STATUS, &status);
  171. if (!(status & (PCI_ERR_ROOT_UNCOR_RCV|PCI_ERR_ROOT_COR_RCV))) {
  172. spin_unlock_irqrestore(&rpc->e_lock, flags);
  173. return IRQ_NONE;
  174. }
  175. /* Read error source and clear error status */
  176. pci_read_config_dword(pdev->port, pos + PCI_ERR_ROOT_ERR_SRC, &id);
  177. pci_write_config_dword(pdev->port, pos + PCI_ERR_ROOT_STATUS, status);
  178. /* Store error source for later DPC handler */
  179. next_prod_idx = rpc->prod_idx + 1;
  180. if (next_prod_idx == AER_ERROR_SOURCES_MAX)
  181. next_prod_idx = 0;
  182. if (next_prod_idx == rpc->cons_idx) {
  183. /*
  184. * Error Storm Condition - possibly the same error occurred.
  185. * Drop the error.
  186. */
  187. spin_unlock_irqrestore(&rpc->e_lock, flags);
  188. return IRQ_HANDLED;
  189. }
  190. rpc->e_sources[rpc->prod_idx].status = status;
  191. rpc->e_sources[rpc->prod_idx].id = id;
  192. rpc->prod_idx = next_prod_idx;
  193. spin_unlock_irqrestore(&rpc->e_lock, flags);
  194. /* Invoke DPC handler */
  195. schedule_work(&rpc->dpc_handler);
  196. return IRQ_HANDLED;
  197. }
  198. EXPORT_SYMBOL_GPL(aer_irq);
  199. /**
  200. * aer_alloc_rpc - allocate Root Port data structure
  201. * @dev: pointer to the pcie_dev data structure
  202. *
  203. * Invoked when Root Port's AER service is loaded.
  204. */
  205. static struct aer_rpc *aer_alloc_rpc(struct pcie_device *dev)
  206. {
  207. struct aer_rpc *rpc;
  208. rpc = kzalloc(sizeof(struct aer_rpc), GFP_KERNEL);
  209. if (!rpc)
  210. return NULL;
  211. /* Initialize Root lock access, e_lock, to Root Error Status Reg */
  212. spin_lock_init(&rpc->e_lock);
  213. rpc->rpd = dev;
  214. INIT_WORK(&rpc->dpc_handler, aer_isr);
  215. mutex_init(&rpc->rpc_mutex);
  216. /* Use PCIe bus function to store rpc into PCIe device */
  217. set_service_data(dev, rpc);
  218. return rpc;
  219. }
  220. /**
  221. * aer_remove - clean up resources
  222. * @dev: pointer to the pcie_dev data structure
  223. *
  224. * Invoked when PCI Express bus unloads or AER probe fails.
  225. */
  226. static void aer_remove(struct pcie_device *dev)
  227. {
  228. struct aer_rpc *rpc = get_service_data(dev);
  229. if (rpc) {
  230. /* If register interrupt service, it must be free. */
  231. if (rpc->isr)
  232. free_irq(dev->irq, dev);
  233. flush_work(&rpc->dpc_handler);
  234. aer_disable_rootport(rpc);
  235. kfree(rpc);
  236. set_service_data(dev, NULL);
  237. }
  238. }
  239. /**
  240. * aer_probe - initialize resources
  241. * @dev: pointer to the pcie_dev data structure
  242. *
  243. * Invoked when PCI Express bus loads AER service driver.
  244. */
  245. static int aer_probe(struct pcie_device *dev)
  246. {
  247. int status;
  248. struct aer_rpc *rpc;
  249. struct device *device = &dev->port->dev;
  250. /* Alloc rpc data structure */
  251. rpc = aer_alloc_rpc(dev);
  252. if (!rpc) {
  253. dev_printk(KERN_DEBUG, device, "alloc AER rpc failed\n");
  254. aer_remove(dev);
  255. return -ENOMEM;
  256. }
  257. /* Request IRQ ISR */
  258. status = request_irq(dev->irq, aer_irq, IRQF_SHARED, "aerdrv", dev);
  259. if (status) {
  260. dev_printk(KERN_DEBUG, device, "request AER IRQ %d failed\n",
  261. dev->irq);
  262. aer_remove(dev);
  263. return status;
  264. }
  265. rpc->isr = 1;
  266. aer_enable_rootport(rpc);
  267. dev_info(device, "AER enabled with IRQ %d\n", dev->irq);
  268. return 0;
  269. }
  270. /**
  271. * aer_root_reset - reset link on Root Port
  272. * @dev: pointer to Root Port's pci_dev data structure
  273. *
  274. * Invoked by Port Bus driver when performing link reset at Root Port.
  275. */
  276. static pci_ers_result_t aer_root_reset(struct pci_dev *dev)
  277. {
  278. u32 reg32;
  279. int pos;
  280. pos = dev->aer_cap;
  281. /* Disable Root's interrupt in response to error messages */
  282. pci_read_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, &reg32);
  283. reg32 &= ~ROOT_PORT_INTR_ON_MESG_MASK;
  284. pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, reg32);
  285. pci_reset_bridge_secondary_bus(dev);
  286. dev_printk(KERN_DEBUG, &dev->dev, "Root Port link has been reset\n");
  287. /* Clear Root Error Status */
  288. pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &reg32);
  289. pci_write_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, reg32);
  290. /* Enable Root Port's interrupt in response to error messages */
  291. pci_read_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, &reg32);
  292. reg32 |= ROOT_PORT_INTR_ON_MESG_MASK;
  293. pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, reg32);
  294. return PCI_ERS_RESULT_RECOVERED;
  295. }
  296. /**
  297. * aer_error_detected - update severity status
  298. * @dev: pointer to Root Port's pci_dev data structure
  299. * @error: error severity being notified by port bus
  300. *
  301. * Invoked by Port Bus driver during error recovery.
  302. */
  303. static pci_ers_result_t aer_error_detected(struct pci_dev *dev,
  304. enum pci_channel_state error)
  305. {
  306. /* Root Port has no impact. Always recovers. */
  307. return PCI_ERS_RESULT_CAN_RECOVER;
  308. }
  309. /**
  310. * aer_error_resume - clean up corresponding error status bits
  311. * @dev: pointer to Root Port's pci_dev data structure
  312. *
  313. * Invoked by Port Bus driver during nonfatal recovery.
  314. */
  315. static void aer_error_resume(struct pci_dev *dev)
  316. {
  317. int pos;
  318. u32 status, mask;
  319. u16 reg16;
  320. /* Clean up Root device status */
  321. pcie_capability_read_word(dev, PCI_EXP_DEVSTA, &reg16);
  322. pcie_capability_write_word(dev, PCI_EXP_DEVSTA, reg16);
  323. /* Clean AER Root Error Status */
  324. pos = dev->aer_cap;
  325. pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status);
  326. pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &mask);
  327. if (dev->error_state == pci_channel_io_normal)
  328. status &= ~mask; /* Clear corresponding nonfatal bits */
  329. else
  330. status &= mask; /* Clear corresponding fatal bits */
  331. pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, status);
  332. }
  333. /**
  334. * aer_service_init - register AER root service driver
  335. *
  336. * Invoked when AER root service driver is loaded.
  337. */
  338. static int __init aer_service_init(void)
  339. {
  340. if (!pci_aer_available() || aer_acpi_firmware_first())
  341. return -ENXIO;
  342. return pcie_port_service_register(&aerdriver);
  343. }
  344. device_initcall(aer_service_init);