portdrv_core.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. /*
  2. * File: portdrv_core.c
  3. * Purpose: PCI Express Port Bus Driver's Core Functions
  4. *
  5. * Copyright (C) 2004 Intel
  6. * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
  7. */
  8. #include <linux/module.h>
  9. #include <linux/pci.h>
  10. #include <linux/kernel.h>
  11. #include <linux/errno.h>
  12. #include <linux/pm.h>
  13. #include <linux/string.h>
  14. #include <linux/slab.h>
  15. #include <linux/pcieport_if.h>
  16. #include "portdrv.h"
  17. extern int pcie_mch_quirk; /* MSI-quirk Indicator */
  18. static int pcie_port_probe_service(struct device *dev)
  19. {
  20. struct pcie_device *pciedev;
  21. struct pcie_port_service_driver *driver;
  22. int status;
  23. if (!dev || !dev->driver)
  24. return -ENODEV;
  25. driver = to_service_driver(dev->driver);
  26. if (!driver || !driver->probe)
  27. return -ENODEV;
  28. pciedev = to_pcie_device(dev);
  29. status = driver->probe(pciedev, driver->id_table);
  30. if (!status) {
  31. dev_printk(KERN_DEBUG, dev, "service driver %s loaded\n",
  32. driver->name);
  33. get_device(dev);
  34. }
  35. return status;
  36. }
  37. static int pcie_port_remove_service(struct device *dev)
  38. {
  39. struct pcie_device *pciedev;
  40. struct pcie_port_service_driver *driver;
  41. if (!dev || !dev->driver)
  42. return 0;
  43. pciedev = to_pcie_device(dev);
  44. driver = to_service_driver(dev->driver);
  45. if (driver && driver->remove) {
  46. dev_printk(KERN_DEBUG, dev, "unloading service driver %s\n",
  47. driver->name);
  48. driver->remove(pciedev);
  49. put_device(dev);
  50. }
  51. return 0;
  52. }
  53. static void pcie_port_shutdown_service(struct device *dev) {}
  54. /**
  55. * release_pcie_device - free PCI Express port service device structure
  56. * @dev: Port service device to release
  57. *
  58. * Invoked automatically when device is being removed in response to
  59. * device_unregister(dev). Release all resources being claimed.
  60. */
  61. static void release_pcie_device(struct device *dev)
  62. {
  63. kfree(to_pcie_device(dev));
  64. }
  65. static int is_msi_quirked(struct pci_dev *dev)
  66. {
  67. int port_type, quirk = 0;
  68. u16 reg16;
  69. pci_read_config_word(dev,
  70. pci_find_capability(dev, PCI_CAP_ID_EXP) +
  71. PCIE_CAPABILITIES_REG, &reg16);
  72. port_type = (reg16 >> 4) & PORT_TYPE_MASK;
  73. switch(port_type) {
  74. case PCIE_RC_PORT:
  75. if (pcie_mch_quirk == 1)
  76. quirk = 1;
  77. break;
  78. case PCIE_SW_UPSTREAM_PORT:
  79. case PCIE_SW_DOWNSTREAM_PORT:
  80. default:
  81. break;
  82. }
  83. return quirk;
  84. }
  85. /**
  86. * assign_interrupt_mode - choose interrupt mode for PCI Express port services
  87. * (INTx, MSI-X, MSI) and set up vectors
  88. * @dev: PCI Express port to handle
  89. * @vectors: Array of interrupt vectors to populate
  90. * @mask: Bitmask of port capabilities returned by get_port_device_capability()
  91. *
  92. * Return value: Interrupt mode associated with the port
  93. */
  94. static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask)
  95. {
  96. int i, pos, nvec, status = -EINVAL;
  97. int interrupt_mode = PCIE_PORT_INTx_MODE;
  98. /* Set INTx as default */
  99. for (i = 0, nvec = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
  100. if (mask & (1 << i))
  101. nvec++;
  102. vectors[i] = dev->irq;
  103. }
  104. /* Check MSI quirk */
  105. if (is_msi_quirked(dev))
  106. return interrupt_mode;
  107. /* Select MSI-X over MSI if supported */
  108. pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
  109. if (pos) {
  110. struct msix_entry msix_entries[PCIE_PORT_DEVICE_MAXSERVICES] =
  111. {{0, 0}, {0, 1}, {0, 2}, {0, 3}};
  112. status = pci_enable_msix(dev, msix_entries, nvec);
  113. if (!status) {
  114. int j = 0;
  115. interrupt_mode = PCIE_PORT_MSIX_MODE;
  116. for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
  117. if (mask & (1 << i))
  118. vectors[i] = msix_entries[j++].vector;
  119. }
  120. }
  121. }
  122. if (status) {
  123. pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
  124. if (pos) {
  125. status = pci_enable_msi(dev);
  126. if (!status) {
  127. interrupt_mode = PCIE_PORT_MSI_MODE;
  128. for (i = 0;i < PCIE_PORT_DEVICE_MAXSERVICES;i++)
  129. vectors[i] = dev->irq;
  130. }
  131. }
  132. }
  133. return interrupt_mode;
  134. }
  135. /**
  136. * get_port_device_capability - discover capabilities of a PCI Express port
  137. * @dev: PCI Express port to examine
  138. *
  139. * The capabilities are read from the port's PCI Express configuration registers
  140. * as described in PCI Express Base Specification 1.0a sections 7.8.2, 7.8.9 and
  141. * 7.9 - 7.11.
  142. *
  143. * Return value: Bitmask of discovered port capabilities
  144. */
  145. static int get_port_device_capability(struct pci_dev *dev)
  146. {
  147. int services = 0, pos;
  148. u16 reg16;
  149. u32 reg32;
  150. pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
  151. pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, &reg16);
  152. /* Hot-Plug Capable */
  153. if (reg16 & PORT_TO_SLOT_MASK) {
  154. pci_read_config_dword(dev,
  155. pos + PCIE_SLOT_CAPABILITIES_REG, &reg32);
  156. if (reg32 & SLOT_HP_CAPABLE_MASK)
  157. services |= PCIE_PORT_SERVICE_HP;
  158. }
  159. /* PME Capable - root port capability */
  160. if (((reg16 >> 4) & PORT_TYPE_MASK) == PCIE_RC_PORT)
  161. services |= PCIE_PORT_SERVICE_PME;
  162. if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR))
  163. services |= PCIE_PORT_SERVICE_AER;
  164. if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC))
  165. services |= PCIE_PORT_SERVICE_VC;
  166. return services;
  167. }
  168. /**
  169. * pcie_device_init - initialize PCI Express port service device
  170. * @dev: Port service device to initialize
  171. * @parent: PCI Express port to associate the service device with
  172. * @port_type: Type of the port
  173. * @service_type: Type of service to associate with the service device
  174. * @irq: Interrupt vector to associate with the service device
  175. * @irq_mode: Interrupt mode of the service (INTx, MSI-X, MSI)
  176. */
  177. static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev,
  178. int port_type, int service_type, int irq, int irq_mode)
  179. {
  180. struct device *device;
  181. dev->port = parent;
  182. dev->interrupt_mode = irq_mode;
  183. dev->irq = irq;
  184. dev->id.vendor = parent->vendor;
  185. dev->id.device = parent->device;
  186. dev->id.port_type = port_type;
  187. dev->id.service_type = (1 << service_type);
  188. /* Initialize generic device interface */
  189. device = &dev->device;
  190. memset(device, 0, sizeof(struct device));
  191. device->bus = &pcie_port_bus_type;
  192. device->driver = NULL;
  193. device->driver_data = NULL;
  194. device->release = release_pcie_device; /* callback to free pcie dev */
  195. dev_set_name(device, "%s:pcie%02x",
  196. pci_name(parent), get_descriptor_id(port_type, service_type));
  197. device->parent = &parent->dev;
  198. }
  199. /**
  200. * alloc_pcie_device - allocate PCI Express port service device structure
  201. * @parent: PCI Express port to associate the service device with
  202. * @port_type: Type of the port
  203. * @service_type: Type of service to associate with the service device
  204. * @irq: Interrupt vector to associate with the service device
  205. * @irq_mode: Interrupt mode of the service (INTx, MSI-X, MSI)
  206. */
  207. static struct pcie_device* alloc_pcie_device(struct pci_dev *parent,
  208. int port_type, int service_type, int irq, int irq_mode)
  209. {
  210. struct pcie_device *device;
  211. device = kzalloc(sizeof(struct pcie_device), GFP_KERNEL);
  212. if (!device)
  213. return NULL;
  214. pcie_device_init(parent, device, port_type, service_type, irq,irq_mode);
  215. return device;
  216. }
  217. /**
  218. * pcie_port_device_probe - check if device is a PCI Express port
  219. * @dev: Device to check
  220. */
  221. int pcie_port_device_probe(struct pci_dev *dev)
  222. {
  223. int pos, type;
  224. u16 reg;
  225. if (!(pos = pci_find_capability(dev, PCI_CAP_ID_EXP)))
  226. return -ENODEV;
  227. pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, &reg);
  228. type = (reg >> 4) & PORT_TYPE_MASK;
  229. if ( type == PCIE_RC_PORT || type == PCIE_SW_UPSTREAM_PORT ||
  230. type == PCIE_SW_DOWNSTREAM_PORT )
  231. return 0;
  232. return -ENODEV;
  233. }
  234. /**
  235. * pcie_port_device_register - register PCI Express port
  236. * @dev: PCI Express port to register
  237. *
  238. * Allocate the port extension structure and register services associated with
  239. * the port.
  240. */
  241. int pcie_port_device_register(struct pci_dev *dev)
  242. {
  243. struct pcie_port_device_ext *p_ext;
  244. int status, type, capabilities, irq_mode, i;
  245. int vectors[PCIE_PORT_DEVICE_MAXSERVICES];
  246. u16 reg16;
  247. /* Allocate port device extension */
  248. if (!(p_ext = kmalloc(sizeof(struct pcie_port_device_ext), GFP_KERNEL)))
  249. return -ENOMEM;
  250. pci_set_drvdata(dev, p_ext);
  251. /* Get port type */
  252. pci_read_config_word(dev,
  253. pci_find_capability(dev, PCI_CAP_ID_EXP) +
  254. PCIE_CAPABILITIES_REG, &reg16);
  255. type = (reg16 >> 4) & PORT_TYPE_MASK;
  256. /* Now get port services */
  257. capabilities = get_port_device_capability(dev);
  258. irq_mode = assign_interrupt_mode(dev, vectors, capabilities);
  259. p_ext->interrupt_mode = irq_mode;
  260. /* Allocate child services if any */
  261. for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
  262. struct pcie_device *child;
  263. if (capabilities & (1 << i)) {
  264. child = alloc_pcie_device(
  265. dev, /* parent */
  266. type, /* port type */
  267. i, /* service type */
  268. vectors[i], /* irq */
  269. irq_mode /* interrupt mode */);
  270. if (child) {
  271. status = device_register(&child->device);
  272. if (status) {
  273. kfree(child);
  274. continue;
  275. }
  276. get_device(&child->device);
  277. }
  278. }
  279. }
  280. return 0;
  281. }
  282. #ifdef CONFIG_PM
  283. static int suspend_iter(struct device *dev, void *data)
  284. {
  285. struct pcie_port_service_driver *service_driver;
  286. pm_message_t state = * (pm_message_t *) data;
  287. if ((dev->bus == &pcie_port_bus_type) &&
  288. (dev->driver)) {
  289. service_driver = to_service_driver(dev->driver);
  290. if (service_driver->suspend)
  291. service_driver->suspend(to_pcie_device(dev), state);
  292. }
  293. return 0;
  294. }
  295. /**
  296. * pcie_port_device_suspend - suspend port services associated with a PCIe port
  297. * @dev: PCI Express port to handle
  298. * @state: Representation of system power management transition in progress
  299. */
  300. int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state)
  301. {
  302. return device_for_each_child(&dev->dev, &state, suspend_iter);
  303. }
  304. static int resume_iter(struct device *dev, void *data)
  305. {
  306. struct pcie_port_service_driver *service_driver;
  307. if ((dev->bus == &pcie_port_bus_type) &&
  308. (dev->driver)) {
  309. service_driver = to_service_driver(dev->driver);
  310. if (service_driver->resume)
  311. service_driver->resume(to_pcie_device(dev));
  312. }
  313. return 0;
  314. }
  315. /**
  316. * pcie_port_device_suspend - resume port services associated with a PCIe port
  317. * @dev: PCI Express port to handle
  318. */
  319. int pcie_port_device_resume(struct pci_dev *dev)
  320. {
  321. return device_for_each_child(&dev->dev, NULL, resume_iter);
  322. }
  323. #endif
  324. static int remove_iter(struct device *dev, void *data)
  325. {
  326. struct pcie_port_service_driver *service_driver;
  327. if (dev->bus == &pcie_port_bus_type) {
  328. if (dev->driver) {
  329. service_driver = to_service_driver(dev->driver);
  330. if (service_driver->remove)
  331. service_driver->remove(to_pcie_device(dev));
  332. }
  333. *(unsigned long*)data = (unsigned long)dev;
  334. return 1;
  335. }
  336. return 0;
  337. }
  338. /**
  339. * pcie_port_device_remove - unregister PCI Express port service devices
  340. * @dev: PCI Express port the service devices to unregister are associated with
  341. *
  342. * Remove PCI Express port service devices associated with given port and
  343. * disable MSI-X or MSI for the port.
  344. */
  345. void pcie_port_device_remove(struct pci_dev *dev)
  346. {
  347. struct device *device;
  348. unsigned long device_addr;
  349. int interrupt_mode = PCIE_PORT_INTx_MODE;
  350. int status;
  351. do {
  352. status = device_for_each_child(&dev->dev, &device_addr, remove_iter);
  353. if (status) {
  354. device = (struct device*)device_addr;
  355. interrupt_mode = (to_pcie_device(device))->interrupt_mode;
  356. put_device(device);
  357. device_unregister(device);
  358. }
  359. } while (status);
  360. /* Switch to INTx by default if MSI enabled */
  361. if (interrupt_mode == PCIE_PORT_MSIX_MODE)
  362. pci_disable_msix(dev);
  363. else if (interrupt_mode == PCIE_PORT_MSI_MODE)
  364. pci_disable_msi(dev);
  365. }
  366. int pcie_port_bus_register(void)
  367. {
  368. return bus_register(&pcie_port_bus_type);
  369. }
  370. void pcie_port_bus_unregister(void)
  371. {
  372. bus_unregister(&pcie_port_bus_type);
  373. }
  374. int pcie_port_service_register(struct pcie_port_service_driver *new)
  375. {
  376. new->driver.name = (char *)new->name;
  377. new->driver.bus = &pcie_port_bus_type;
  378. new->driver.probe = pcie_port_probe_service;
  379. new->driver.remove = pcie_port_remove_service;
  380. new->driver.shutdown = pcie_port_shutdown_service;
  381. return driver_register(&new->driver);
  382. }
  383. void pcie_port_service_unregister(struct pcie_port_service_driver *new)
  384. {
  385. driver_unregister(&new->driver);
  386. }
  387. EXPORT_SYMBOL(pcie_port_service_register);
  388. EXPORT_SYMBOL(pcie_port_service_unregister);