diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-22 19:39:28 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-22 19:39:28 -0500 |
commit | e1ba84597c9012b9f9075aac283ac7537d7561ba (patch) | |
tree | 41ab1a74c71ce55e72ef73424346e8e0a7f4616e /Documentation | |
parent | 60eaa0190f6b39dce18eb1975d9773ed8bc9a534 (diff) | |
parent | cef09b808e584c13b7126b83dc37c80b00234137 (diff) |
Merge tag 'pci-v3.14-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI updates from Bjorn Helgaas:
"PCI changes for the v3.14 merge window:
Resource management
- Change pci_bus_region addresses to dma_addr_t (Bjorn Helgaas)
- Support 64-bit AGP BARs (Bjorn Helgaas, Yinghai Lu)
- Add pci_bus_address() to get bus address of a BAR (Bjorn Helgaas)
- Use pci_resource_start() for CPU address of AGP BARs (Bjorn Helgaas)
- Enforce bus address limits in resource allocation (Yinghai Lu)
- Allocate 64-bit BARs above 4G when possible (Yinghai Lu)
- Convert pcibios_resource_to_bus() to take pci_bus, not pci_dev (Yinghai Lu)
PCI device hotplug
- Major rescan/remove locking update (Rafael J. Wysocki)
- Make ioapic builtin only (not modular) (Yinghai Lu)
- Fix release/free issues (Yinghai Lu)
- Clean up pciehp (Bjorn Helgaas)
- Announce pciehp slot info during enumeration (Bjorn Helgaas)
MSI
- Add pci_msi_vec_count(), pci_msix_vec_count() (Alexander Gordeev)
- Add pci_enable_msi_range(), pci_enable_msix_range() (Alexander Gordeev)
- Deprecate "tri-state" interfaces: fail/success/fail+info (Alexander Gordeev)
- Export MSI mode using attributes, not kobjects (Greg Kroah-Hartman)
- Drop "irq" param from *_restore_msi_irqs() (DuanZhenzhong)
SR-IOV
- Clear NumVFs when disabling SR-IOV in sriov_init() (ethan.zhao)
Virtualization
- Add support for save/restore of extended capabilities (Alex Williamson)
- Add Virtual Channel to save/restore support (Alex Williamson)
- Never treat a VF as a multifunction device (Alex Williamson)
- Add pci_try_reset_function(), et al (Alex Williamson)
AER
- Ignore non-PCIe error sources (Betty Dall)
- Support ACPI HEST error sources for domains other than 0 (Betty Dall)
- Consolidate HEST error source parsers (Bjorn Helgaas)
- Add a TLP header print helper (Borislav Petkov)
Freescale i.MX6
- Remove unnecessary code (Fabio Estevam)
- Make reset-gpio optional (Marek Vasut)
- Report "link up" only after link training completes (Marek Vasut)
- Start link in Gen1 before negotiating for Gen2 mode (Marek Vasut)
- Fix PCIe startup code (Richard Zhu)
Marvell MVEBU
- Remove duplicate of_clk_get_by_name() call (Andrew Lunn)
- Drop writes to bridge Secondary Status register (Jason Gunthorpe)
- Obey bridge PCI_COMMAND_MEM and PCI_COMMAND_IO bits (Jason Gunthorpe)
- Support a bridge with no IO port window (Jason Gunthorpe)
- Use max_t() instead of max(resource_size_t,) (Jingoo Han)
- Remove redundant of_match_ptr (Sachin Kamat)
- Call pci_ioremap_io() at startup instead of dynamically (Thomas Petazzoni)
NVIDIA Tegra
- Disable Gen2 for Tegra20 and Tegra30 (Eric Brower)
Renesas R-Car
- Add runtime PM support (Valentine Barshak)
- Fix rcar_pci_probe() return value check (Wei Yongjun)
Synopsys DesignWare
- Fix crash in dw_msi_teardown_irq() (Bjørn Erik Nilsen)
- Remove redundant call to pci_write_config_word() (Bjørn Erik Nilsen)
- Fix missing MSI IRQs (Harro Haan)
- Add dw_pcie prefix before cfg_read/write (Pratyush Anand)
- Fix I/O transfers by using CPU (not realio) address (Pratyush Anand)
- Whitespace cleanup (Jingoo Han)
EISA
- Call put_device() if device_register() fails (Levente Kurusa)
- Revert EISA initialization breakage ((Bjorn Helgaas)
Miscellaneous
- Remove unused code, including PCIe 3.0 interfaces (Stephen Hemminger)
- Prevent bus conflicts while checking for bridge apertures (Bjorn Helgaas)
- Stop clearing bridge Secondary Status when setting up I/O aperture (Bjorn Helgaas)
- Use dev_is_pci() to identify PCI devices (Yijing Wang)
- Deprecate DEFINE_PCI_DEVICE_TABLE (Joe Perches)
- Update documentation 00-INDEX (Erik Ekman)"
* tag 'pci-v3.14-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (119 commits)
Revert "EISA: Initialize device before its resources"
Revert "EISA: Log device resources in dmesg"
vfio-pci: Use pci "try" reset interface
PCI: Check parent kobject in pci_destroy_dev()
xen/pcifront: Use global PCI rescan-remove locking
powerpc/eeh: Use global PCI rescan-remove locking
PCI: Fix pci_check_and_unmask_intx() comment typos
PCI: Add pci_try_reset_function(), pci_try_reset_slot(), pci_try_reset_bus()
MPT / PCI: Use pci_stop_and_remove_bus_device_locked()
platform / x86: Use global PCI rescan-remove locking
PCI: hotplug: Use global PCI rescan-remove locking
pcmcia: Use global PCI rescan-remove locking
ACPI / hotplug / PCI: Use global PCI rescan-remove locking
ACPI / PCI: Use global PCI rescan-remove locking in PCI root hotplug
PCI: Add global pci_lock_rescan_remove()
PCI: Cleanup pci.h whitespace
PCI: Reorder so actual code comes before stubs
PCI/AER: Support ACPI HEST AER error sources for PCI domains other than 0
ACPICA: Add helper macros to extract bus/segment numbers from HEST table.
PCI: Make local functions static
...
Diffstat (limited to 'Documentation')
-rw-r--r-- | Documentation/ABI/testing/sysfs-bus-pci | 11 | ||||
-rw-r--r-- | Documentation/PCI/00-INDEX | 4 | ||||
-rw-r--r-- | Documentation/PCI/MSI-HOWTO.txt | 308 | ||||
-rw-r--r-- | Documentation/PCI/pci.txt | 6 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/pci/designware-pcie.txt | 2 |
5 files changed, 222 insertions, 109 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-pci b/Documentation/ABI/testing/sysfs-bus-pci index 5210a51c90fd..a3c5a6685036 100644 --- a/Documentation/ABI/testing/sysfs-bus-pci +++ b/Documentation/ABI/testing/sysfs-bus-pci | |||
@@ -70,18 +70,15 @@ Date: September, 2011 | |||
70 | Contact: Neil Horman <nhorman@tuxdriver.com> | 70 | Contact: Neil Horman <nhorman@tuxdriver.com> |
71 | Description: | 71 | Description: |
72 | The /sys/devices/.../msi_irqs directory contains a variable set | 72 | The /sys/devices/.../msi_irqs directory contains a variable set |
73 | of sub-directories, with each sub-directory being named after a | 73 | of files, with each file being named after a corresponding msi |
74 | corresponding msi irq vector allocated to that device. Each | 74 | irq vector allocated to that device. |
75 | numbered sub-directory N contains attributes of that irq. | ||
76 | Note that this directory is not created for device drivers which | ||
77 | do not support msi irqs | ||
78 | 75 | ||
79 | What: /sys/bus/pci/devices/.../msi_irqs/<N>/mode | 76 | What: /sys/bus/pci/devices/.../msi_irqs/<N> |
80 | Date: September 2011 | 77 | Date: September 2011 |
81 | Contact: Neil Horman <nhorman@tuxdriver.com> | 78 | Contact: Neil Horman <nhorman@tuxdriver.com> |
82 | Description: | 79 | Description: |
83 | This attribute indicates the mode that the irq vector named by | 80 | This attribute indicates the mode that the irq vector named by |
84 | the parent directory is in (msi vs. msix) | 81 | the file is in (msi vs. msix) |
85 | 82 | ||
86 | What: /sys/bus/pci/devices/.../remove | 83 | What: /sys/bus/pci/devices/.../remove |
87 | Date: January 2009 | 84 | Date: January 2009 |
diff --git a/Documentation/PCI/00-INDEX b/Documentation/PCI/00-INDEX index 812b17fe3ed0..147231f1613e 100644 --- a/Documentation/PCI/00-INDEX +++ b/Documentation/PCI/00-INDEX | |||
@@ -2,12 +2,12 @@ | |||
2 | - this file | 2 | - this file |
3 | MSI-HOWTO.txt | 3 | MSI-HOWTO.txt |
4 | - the Message Signaled Interrupts (MSI) Driver Guide HOWTO and FAQ. | 4 | - the Message Signaled Interrupts (MSI) Driver Guide HOWTO and FAQ. |
5 | PCI-DMA-mapping.txt | ||
6 | - info for PCI drivers using DMA portably across all platforms | ||
7 | PCIEBUS-HOWTO.txt | 5 | PCIEBUS-HOWTO.txt |
8 | - a guide describing the PCI Express Port Bus driver | 6 | - a guide describing the PCI Express Port Bus driver |
9 | pci-error-recovery.txt | 7 | pci-error-recovery.txt |
10 | - info on PCI error recovery | 8 | - info on PCI error recovery |
9 | pci-iov-howto.txt | ||
10 | - the PCI Express I/O Virtualization HOWTO | ||
11 | pci.txt | 11 | pci.txt |
12 | - info on the PCI subsystem for device driver authors | 12 | - info on the PCI subsystem for device driver authors |
13 | pcieaer-howto.txt | 13 | pcieaer-howto.txt |
diff --git a/Documentation/PCI/MSI-HOWTO.txt b/Documentation/PCI/MSI-HOWTO.txt index a09178086c30..a8d01005f480 100644 --- a/Documentation/PCI/MSI-HOWTO.txt +++ b/Documentation/PCI/MSI-HOWTO.txt | |||
@@ -82,93 +82,111 @@ Most of the hard work is done for the driver in the PCI layer. It simply | |||
82 | has to request that the PCI layer set up the MSI capability for this | 82 | has to request that the PCI layer set up the MSI capability for this |
83 | device. | 83 | device. |
84 | 84 | ||
85 | 4.2.1 pci_enable_msi | 85 | 4.2.1 pci_enable_msi_range |
86 | 86 | ||
87 | int pci_enable_msi(struct pci_dev *dev) | 87 | int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec) |
88 | 88 | ||
89 | A successful call allocates ONE interrupt to the device, regardless | 89 | This function allows a device driver to request any number of MSI |
90 | of how many MSIs the device supports. The device is switched from | 90 | interrupts within specified range from 'minvec' to 'maxvec'. |
91 | pin-based interrupt mode to MSI mode. The dev->irq number is changed | ||
92 | to a new number which represents the message signaled interrupt; | ||
93 | consequently, this function should be called before the driver calls | ||
94 | request_irq(), because an MSI is delivered via a vector that is | ||
95 | different from the vector of a pin-based interrupt. | ||
96 | 91 | ||
97 | 4.2.2 pci_enable_msi_block | 92 | If this function returns a positive number it indicates the number of |
93 | MSI interrupts that have been successfully allocated. In this case | ||
94 | the device is switched from pin-based interrupt mode to MSI mode and | ||
95 | updates dev->irq to be the lowest of the new interrupts assigned to it. | ||
96 | The other interrupts assigned to the device are in the range dev->irq | ||
97 | to dev->irq + returned value - 1. Device driver can use the returned | ||
98 | number of successfully allocated MSI interrupts to further allocate | ||
99 | and initialize device resources. | ||
98 | 100 | ||
99 | int pci_enable_msi_block(struct pci_dev *dev, int count) | 101 | If this function returns a negative number, it indicates an error and |
102 | the driver should not attempt to request any more MSI interrupts for | ||
103 | this device. | ||
100 | 104 | ||
101 | This variation on the above call allows a device driver to request multiple | 105 | This function should be called before the driver calls request_irq(), |
102 | MSIs. The MSI specification only allows interrupts to be allocated in | 106 | because MSI interrupts are delivered via vectors that are different |
103 | powers of two, up to a maximum of 2^5 (32). | 107 | from the vector of a pin-based interrupt. |
104 | 108 | ||
105 | If this function returns 0, it has succeeded in allocating at least as many | 109 | It is ideal if drivers can cope with a variable number of MSI interrupts; |
106 | interrupts as the driver requested (it may have allocated more in order | 110 | there are many reasons why the platform may not be able to provide the |
107 | to satisfy the power-of-two requirement). In this case, the function | 111 | exact number that a driver asks for. |
108 | enables MSI on this device and updates dev->irq to be the lowest of | ||
109 | the new interrupts assigned to it. The other interrupts assigned to | ||
110 | the device are in the range dev->irq to dev->irq + count - 1. | ||
111 | 112 | ||
112 | If this function returns a negative number, it indicates an error and | 113 | There could be devices that can not operate with just any number of MSI |
113 | the driver should not attempt to request any more MSI interrupts for | 114 | interrupts within a range. See chapter 4.3.1.3 to get the idea how to |
114 | this device. If this function returns a positive number, it is | 115 | handle such devices for MSI-X - the same logic applies to MSI. |
115 | less than 'count' and indicates the number of interrupts that could have | ||
116 | been allocated. In neither case is the irq value updated or the device | ||
117 | switched into MSI mode. | ||
118 | |||
119 | The device driver must decide what action to take if | ||
120 | pci_enable_msi_block() returns a value less than the number requested. | ||
121 | For instance, the driver could still make use of fewer interrupts; | ||
122 | in this case the driver should call pci_enable_msi_block() | ||
123 | again. Note that it is not guaranteed to succeed, even when the | ||
124 | 'count' has been reduced to the value returned from a previous call to | ||
125 | pci_enable_msi_block(). This is because there are multiple constraints | ||
126 | on the number of vectors that can be allocated; pci_enable_msi_block() | ||
127 | returns as soon as it finds any constraint that doesn't allow the | ||
128 | call to succeed. | ||
129 | |||
130 | 4.2.3 pci_enable_msi_block_auto | ||
131 | |||
132 | int pci_enable_msi_block_auto(struct pci_dev *dev, unsigned int *count) | ||
133 | |||
134 | This variation on pci_enable_msi() call allows a device driver to request | ||
135 | the maximum possible number of MSIs. The MSI specification only allows | ||
136 | interrupts to be allocated in powers of two, up to a maximum of 2^5 (32). | ||
137 | |||
138 | If this function returns a positive number, it indicates that it has | ||
139 | succeeded and the returned value is the number of allocated interrupts. In | ||
140 | this case, the function enables MSI on this device and updates dev->irq to | ||
141 | be the lowest of the new interrupts assigned to it. The other interrupts | ||
142 | assigned to the device are in the range dev->irq to dev->irq + returned | ||
143 | value - 1. | ||
144 | 116 | ||
145 | If this function returns a negative number, it indicates an error and | 117 | 4.2.1.1 Maximum possible number of MSI interrupts |
146 | the driver should not attempt to request any more MSI interrupts for | 118 | |
147 | this device. | 119 | The typical usage of MSI interrupts is to allocate as many vectors as |
120 | possible, likely up to the limit returned by pci_msi_vec_count() function: | ||
121 | |||
122 | static int foo_driver_enable_msi(struct pci_dev *pdev, int nvec) | ||
123 | { | ||
124 | return pci_enable_msi_range(pdev, 1, nvec); | ||
125 | } | ||
126 | |||
127 | Note the value of 'minvec' parameter is 1. As 'minvec' is inclusive, | ||
128 | the value of 0 would be meaningless and could result in error. | ||
148 | 129 | ||
149 | If the device driver needs to know the number of interrupts the device | 130 | Some devices have a minimal limit on number of MSI interrupts. |
150 | supports it can pass the pointer count where that number is stored. The | 131 | In this case the function could look like this: |
151 | device driver must decide what action to take if pci_enable_msi_block_auto() | ||
152 | succeeds, but returns a value less than the number of interrupts supported. | ||
153 | If the device driver does not need to know the number of interrupts | ||
154 | supported, it can set the pointer count to NULL. | ||
155 | 132 | ||
156 | 4.2.4 pci_disable_msi | 133 | static int foo_driver_enable_msi(struct pci_dev *pdev, int nvec) |
134 | { | ||
135 | return pci_enable_msi_range(pdev, FOO_DRIVER_MINIMUM_NVEC, nvec); | ||
136 | } | ||
137 | |||
138 | 4.2.1.2 Exact number of MSI interrupts | ||
139 | |||
140 | If a driver is unable or unwilling to deal with a variable number of MSI | ||
141 | interrupts it could request a particular number of interrupts by passing | ||
142 | that number to pci_enable_msi_range() function as both 'minvec' and 'maxvec' | ||
143 | parameters: | ||
144 | |||
145 | static int foo_driver_enable_msi(struct pci_dev *pdev, int nvec) | ||
146 | { | ||
147 | return pci_enable_msi_range(pdev, nvec, nvec); | ||
148 | } | ||
149 | |||
150 | 4.2.1.3 Single MSI mode | ||
151 | |||
152 | The most notorious example of the request type described above is | ||
153 | enabling the single MSI mode for a device. It could be done by passing | ||
154 | two 1s as 'minvec' and 'maxvec': | ||
155 | |||
156 | static int foo_driver_enable_single_msi(struct pci_dev *pdev) | ||
157 | { | ||
158 | return pci_enable_msi_range(pdev, 1, 1); | ||
159 | } | ||
160 | |||
161 | 4.2.2 pci_disable_msi | ||
157 | 162 | ||
158 | void pci_disable_msi(struct pci_dev *dev) | 163 | void pci_disable_msi(struct pci_dev *dev) |
159 | 164 | ||
160 | This function should be used to undo the effect of pci_enable_msi() or | 165 | This function should be used to undo the effect of pci_enable_msi_range(). |
161 | pci_enable_msi_block() or pci_enable_msi_block_auto(). Calling it restores | 166 | Calling it restores dev->irq to the pin-based interrupt number and frees |
162 | dev->irq to the pin-based interrupt number and frees the previously | 167 | the previously allocated MSIs. The interrupts may subsequently be assigned |
163 | allocated message signaled interrupt(s). The interrupt may subsequently be | 168 | to another device, so drivers should not cache the value of dev->irq. |
164 | assigned to another device, so drivers should not cache the value of | ||
165 | dev->irq. | ||
166 | 169 | ||
167 | Before calling this function, a device driver must always call free_irq() | 170 | Before calling this function, a device driver must always call free_irq() |
168 | on any interrupt for which it previously called request_irq(). | 171 | on any interrupt for which it previously called request_irq(). |
169 | Failure to do so results in a BUG_ON(), leaving the device with | 172 | Failure to do so results in a BUG_ON(), leaving the device with |
170 | MSI enabled and thus leaking its vector. | 173 | MSI enabled and thus leaking its vector. |
171 | 174 | ||
175 | 4.2.3 pci_msi_vec_count | ||
176 | |||
177 | int pci_msi_vec_count(struct pci_dev *dev) | ||
178 | |||
179 | This function could be used to retrieve the number of MSI vectors the | ||
180 | device requested (via the Multiple Message Capable register). The MSI | ||
181 | specification only allows the returned value to be a power of two, | ||
182 | up to a maximum of 2^5 (32). | ||
183 | |||
184 | If this function returns a negative number, it indicates the device is | ||
185 | not capable of sending MSIs. | ||
186 | |||
187 | If this function returns a positive number, it indicates the maximum | ||
188 | number of MSI interrupt vectors that could be allocated. | ||
189 | |||
172 | 4.3 Using MSI-X | 190 | 4.3 Using MSI-X |
173 | 191 | ||
174 | The MSI-X capability is much more flexible than the MSI capability. | 192 | The MSI-X capability is much more flexible than the MSI capability. |
@@ -188,26 +206,31 @@ in each element of the array to indicate for which entries the kernel | |||
188 | should assign interrupts; it is invalid to fill in two entries with the | 206 | should assign interrupts; it is invalid to fill in two entries with the |
189 | same number. | 207 | same number. |
190 | 208 | ||
191 | 4.3.1 pci_enable_msix | 209 | 4.3.1 pci_enable_msix_range |
192 | 210 | ||
193 | int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec) | 211 | int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, |
212 | int minvec, int maxvec) | ||
194 | 213 | ||
195 | Calling this function asks the PCI subsystem to allocate 'nvec' MSIs. | 214 | Calling this function asks the PCI subsystem to allocate any number of |
215 | MSI-X interrupts within specified range from 'minvec' to 'maxvec'. | ||
196 | The 'entries' argument is a pointer to an array of msix_entry structs | 216 | The 'entries' argument is a pointer to an array of msix_entry structs |
197 | which should be at least 'nvec' entries in size. On success, the | 217 | which should be at least 'maxvec' entries in size. |
198 | device is switched into MSI-X mode and the function returns 0. | 218 | |
199 | The 'vector' member in each entry is populated with the interrupt number; | 219 | On success, the device is switched into MSI-X mode and the function |
220 | returns the number of MSI-X interrupts that have been successfully | ||
221 | allocated. In this case the 'vector' member in entries numbered from | ||
222 | 0 to the returned value - 1 is populated with the interrupt number; | ||
200 | the driver should then call request_irq() for each 'vector' that it | 223 | the driver should then call request_irq() for each 'vector' that it |
201 | decides to use. The device driver is responsible for keeping track of the | 224 | decides to use. The device driver is responsible for keeping track of the |
202 | interrupts assigned to the MSI-X vectors so it can free them again later. | 225 | interrupts assigned to the MSI-X vectors so it can free them again later. |
226 | Device driver can use the returned number of successfully allocated MSI-X | ||
227 | interrupts to further allocate and initialize device resources. | ||
203 | 228 | ||
204 | If this function returns a negative number, it indicates an error and | 229 | If this function returns a negative number, it indicates an error and |
205 | the driver should not attempt to allocate any more MSI-X interrupts for | 230 | the driver should not attempt to allocate any more MSI-X interrupts for |
206 | this device. If it returns a positive number, it indicates the maximum | 231 | this device. |
207 | number of interrupt vectors that could have been allocated. See example | ||
208 | below. | ||
209 | 232 | ||
210 | This function, in contrast with pci_enable_msi(), does not adjust | 233 | This function, in contrast with pci_enable_msi_range(), does not adjust |
211 | dev->irq. The device will not generate interrupts for this interrupt | 234 | dev->irq. The device will not generate interrupts for this interrupt |
212 | number once MSI-X is enabled. | 235 | number once MSI-X is enabled. |
213 | 236 | ||
@@ -218,28 +241,103 @@ It is ideal if drivers can cope with a variable number of MSI-X interrupts; | |||
218 | there are many reasons why the platform may not be able to provide the | 241 | there are many reasons why the platform may not be able to provide the |
219 | exact number that a driver asks for. | 242 | exact number that a driver asks for. |
220 | 243 | ||
221 | A request loop to achieve that might look like: | 244 | There could be devices that can not operate with just any number of MSI-X |
245 | interrupts within a range. E.g., an network adapter might need let's say | ||
246 | four vectors per each queue it provides. Therefore, a number of MSI-X | ||
247 | interrupts allocated should be a multiple of four. In this case interface | ||
248 | pci_enable_msix_range() can not be used alone to request MSI-X interrupts | ||
249 | (since it can allocate any number within the range, without any notion of | ||
250 | the multiple of four) and the device driver should master a custom logic | ||
251 | to request the required number of MSI-X interrupts. | ||
252 | |||
253 | 4.3.1.1 Maximum possible number of MSI-X interrupts | ||
254 | |||
255 | The typical usage of MSI-X interrupts is to allocate as many vectors as | ||
256 | possible, likely up to the limit returned by pci_msix_vec_count() function: | ||
222 | 257 | ||
223 | static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec) | 258 | static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec) |
224 | { | 259 | { |
225 | while (nvec >= FOO_DRIVER_MINIMUM_NVEC) { | 260 | return pci_enable_msi_range(adapter->pdev, adapter->msix_entries, |
226 | rc = pci_enable_msix(adapter->pdev, | 261 | 1, nvec); |
227 | adapter->msix_entries, nvec); | 262 | } |
228 | if (rc > 0) | 263 | |
229 | nvec = rc; | 264 | Note the value of 'minvec' parameter is 1. As 'minvec' is inclusive, |
230 | else | 265 | the value of 0 would be meaningless and could result in error. |
231 | return rc; | 266 | |
267 | Some devices have a minimal limit on number of MSI-X interrupts. | ||
268 | In this case the function could look like this: | ||
269 | |||
270 | static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec) | ||
271 | { | ||
272 | return pci_enable_msi_range(adapter->pdev, adapter->msix_entries, | ||
273 | FOO_DRIVER_MINIMUM_NVEC, nvec); | ||
274 | } | ||
275 | |||
276 | 4.3.1.2 Exact number of MSI-X interrupts | ||
277 | |||
278 | If a driver is unable or unwilling to deal with a variable number of MSI-X | ||
279 | interrupts it could request a particular number of interrupts by passing | ||
280 | that number to pci_enable_msix_range() function as both 'minvec' and 'maxvec' | ||
281 | parameters: | ||
282 | |||
283 | static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec) | ||
284 | { | ||
285 | return pci_enable_msi_range(adapter->pdev, adapter->msix_entries, | ||
286 | nvec, nvec); | ||
287 | } | ||
288 | |||
289 | 4.3.1.3 Specific requirements to the number of MSI-X interrupts | ||
290 | |||
291 | As noted above, there could be devices that can not operate with just any | ||
292 | number of MSI-X interrupts within a range. E.g., let's assume a device that | ||
293 | is only capable sending the number of MSI-X interrupts which is a power of | ||
294 | two. A routine that enables MSI-X mode for such device might look like this: | ||
295 | |||
296 | /* | ||
297 | * Assume 'minvec' and 'maxvec' are non-zero | ||
298 | */ | ||
299 | static int foo_driver_enable_msix(struct foo_adapter *adapter, | ||
300 | int minvec, int maxvec) | ||
301 | { | ||
302 | int rc; | ||
303 | |||
304 | minvec = roundup_pow_of_two(minvec); | ||
305 | maxvec = rounddown_pow_of_two(maxvec); | ||
306 | |||
307 | if (minvec > maxvec) | ||
308 | return -ERANGE; | ||
309 | |||
310 | retry: | ||
311 | rc = pci_enable_msix_range(adapter->pdev, adapter->msix_entries, | ||
312 | maxvec, maxvec); | ||
313 | /* | ||
314 | * -ENOSPC is the only error code allowed to be analized | ||
315 | */ | ||
316 | if (rc == -ENOSPC) { | ||
317 | if (maxvec == 1) | ||
318 | return -ENOSPC; | ||
319 | |||
320 | maxvec /= 2; | ||
321 | |||
322 | if (minvec > maxvec) | ||
323 | return -ENOSPC; | ||
324 | |||
325 | goto retry; | ||
232 | } | 326 | } |
233 | 327 | ||
234 | return -ENOSPC; | 328 | return rc; |
235 | } | 329 | } |
236 | 330 | ||
331 | Note how pci_enable_msix_range() return value is analized for a fallback - | ||
332 | any error code other than -ENOSPC indicates a fatal error and should not | ||
333 | be retried. | ||
334 | |||
237 | 4.3.2 pci_disable_msix | 335 | 4.3.2 pci_disable_msix |
238 | 336 | ||
239 | void pci_disable_msix(struct pci_dev *dev) | 337 | void pci_disable_msix(struct pci_dev *dev) |
240 | 338 | ||
241 | This function should be used to undo the effect of pci_enable_msix(). It frees | 339 | This function should be used to undo the effect of pci_enable_msix_range(). |
242 | the previously allocated message signaled interrupts. The interrupts may | 340 | It frees the previously allocated MSI-X interrupts. The interrupts may |
243 | subsequently be assigned to another device, so drivers should not cache | 341 | subsequently be assigned to another device, so drivers should not cache |
244 | the value of the 'vector' elements over a call to pci_disable_msix(). | 342 | the value of the 'vector' elements over a call to pci_disable_msix(). |
245 | 343 | ||
@@ -255,18 +353,32 @@ MSI-X Table. This address is mapped by the PCI subsystem, and should not | |||
255 | be accessed directly by the device driver. If the driver wishes to | 353 | be accessed directly by the device driver. If the driver wishes to |
256 | mask or unmask an interrupt, it should call disable_irq() / enable_irq(). | 354 | mask or unmask an interrupt, it should call disable_irq() / enable_irq(). |
257 | 355 | ||
356 | 4.3.4 pci_msix_vec_count | ||
357 | |||
358 | int pci_msix_vec_count(struct pci_dev *dev) | ||
359 | |||
360 | This function could be used to retrieve number of entries in the device | ||
361 | MSI-X table. | ||
362 | |||
363 | If this function returns a negative number, it indicates the device is | ||
364 | not capable of sending MSI-Xs. | ||
365 | |||
366 | If this function returns a positive number, it indicates the maximum | ||
367 | number of MSI-X interrupt vectors that could be allocated. | ||
368 | |||
258 | 4.4 Handling devices implementing both MSI and MSI-X capabilities | 369 | 4.4 Handling devices implementing both MSI and MSI-X capabilities |
259 | 370 | ||
260 | If a device implements both MSI and MSI-X capabilities, it can | 371 | If a device implements both MSI and MSI-X capabilities, it can |
261 | run in either MSI mode or MSI-X mode, but not both simultaneously. | 372 | run in either MSI mode or MSI-X mode, but not both simultaneously. |
262 | This is a requirement of the PCI spec, and it is enforced by the | 373 | This is a requirement of the PCI spec, and it is enforced by the |
263 | PCI layer. Calling pci_enable_msi() when MSI-X is already enabled or | 374 | PCI layer. Calling pci_enable_msi_range() when MSI-X is already |
264 | pci_enable_msix() when MSI is already enabled results in an error. | 375 | enabled or pci_enable_msix_range() when MSI is already enabled |
265 | If a device driver wishes to switch between MSI and MSI-X at runtime, | 376 | results in an error. If a device driver wishes to switch between MSI |
266 | it must first quiesce the device, then switch it back to pin-interrupt | 377 | and MSI-X at runtime, it must first quiesce the device, then switch |
267 | mode, before calling pci_enable_msi() or pci_enable_msix() and resuming | 378 | it back to pin-interrupt mode, before calling pci_enable_msi_range() |
268 | operation. This is not expected to be a common operation but may be | 379 | or pci_enable_msix_range() and resuming operation. This is not expected |
269 | useful for debugging or testing during development. | 380 | to be a common operation but may be useful for debugging or testing |
381 | during development. | ||
270 | 382 | ||
271 | 4.5 Considerations when using MSIs | 383 | 4.5 Considerations when using MSIs |
272 | 384 | ||
@@ -381,5 +493,5 @@ or disabled (0). If 0 is found in any of the msi_bus files belonging | |||
381 | to bridges between the PCI root and the device, MSIs are disabled. | 493 | to bridges between the PCI root and the device, MSIs are disabled. |
382 | 494 | ||
383 | It is also worth checking the device driver to see whether it supports MSIs. | 495 | It is also worth checking the device driver to see whether it supports MSIs. |
384 | For example, it may contain calls to pci_enable_msi(), pci_enable_msix() or | 496 | For example, it may contain calls to pci_enable_msi_range() or |
385 | pci_enable_msi_block(). | 497 | pci_enable_msix_range(). |
diff --git a/Documentation/PCI/pci.txt b/Documentation/PCI/pci.txt index 6f458564d625..9518006f6675 100644 --- a/Documentation/PCI/pci.txt +++ b/Documentation/PCI/pci.txt | |||
@@ -123,8 +123,10 @@ initialization with a pointer to a structure describing the driver | |||
123 | 123 | ||
124 | 124 | ||
125 | The ID table is an array of struct pci_device_id entries ending with an | 125 | The ID table is an array of struct pci_device_id entries ending with an |
126 | all-zero entry; use of the macro DEFINE_PCI_DEVICE_TABLE is the preferred | 126 | all-zero entry. Definitions with static const are generally preferred. |
127 | method of declaring the table. Each entry consists of: | 127 | Use of the deprecated macro DEFINE_PCI_DEVICE_TABLE should be avoided. |
128 | |||
129 | Each entry consists of: | ||
128 | 130 | ||
129 | vendor,device Vendor and device ID to match (or PCI_ANY_ID) | 131 | vendor,device Vendor and device ID to match (or PCI_ANY_ID) |
130 | 132 | ||
diff --git a/Documentation/devicetree/bindings/pci/designware-pcie.txt b/Documentation/devicetree/bindings/pci/designware-pcie.txt index d5d26d443693..d6fae13ff062 100644 --- a/Documentation/devicetree/bindings/pci/designware-pcie.txt +++ b/Documentation/devicetree/bindings/pci/designware-pcie.txt | |||
@@ -19,6 +19,8 @@ Required properties: | |||
19 | to define the mapping of the PCIe interface to interrupt | 19 | to define the mapping of the PCIe interface to interrupt |
20 | numbers. | 20 | numbers. |
21 | - num-lanes: number of lanes to use | 21 | - num-lanes: number of lanes to use |
22 | |||
23 | Optional properties: | ||
22 | - reset-gpio: gpio pin number of power good signal | 24 | - reset-gpio: gpio pin number of power good signal |
23 | 25 | ||
24 | Optional properties for fsl,imx6q-pcie | 26 | Optional properties for fsl,imx6q-pcie |