diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2014-01-07 19:34:39 -0500 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2014-01-07 19:34:39 -0500 |
commit | 04f982beb900f37bc216d63c9dbc5bdddb4a3d3a (patch) | |
tree | 0138472ccdcc5143e67b6aa78c6c17ff9dcbf494 | |
parent | ccb126545448136d36da8661f2941372554015d1 (diff) | |
parent | 302a2523c277bea0bbe8340312b09507905849ed (diff) |
Merge branch 'pci/msi' into next
* pci/msi:
PCI/MSI: Add pci_enable_msi_range() and pci_enable_msix_range()
PCI/MSI: Add pci_msix_vec_count()
PCI/MSI: Remove pci_enable_msi_block_auto()
PCI/MSI: Add pci_msi_vec_count()
-rw-r--r-- | Documentation/PCI/MSI-HOWTO.txt | 308 | ||||
-rw-r--r-- | drivers/ata/ahci.c | 56 | ||||
-rw-r--r-- | drivers/pci/msi.c | 150 | ||||
-rw-r--r-- | drivers/pci/pcie/portdrv_core.c | 7 | ||||
-rw-r--r-- | include/linux/pci.h | 27 |
5 files changed, 385 insertions, 163 deletions
diff --git a/Documentation/PCI/MSI-HOWTO.txt b/Documentation/PCI/MSI-HOWTO.txt index a4d174e95413..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, 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/drivers/ata/ahci.c b/drivers/ata/ahci.c index e2903d03180e..8516f4d47893 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -1095,26 +1095,40 @@ static inline void ahci_gtf_filter_workaround(struct ata_host *host) | |||
1095 | {} | 1095 | {} |
1096 | #endif | 1096 | #endif |
1097 | 1097 | ||
1098 | int ahci_init_interrupts(struct pci_dev *pdev, struct ahci_host_priv *hpriv) | 1098 | int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, |
1099 | struct ahci_host_priv *hpriv) | ||
1099 | { | 1100 | { |
1100 | int rc; | 1101 | int rc, nvec; |
1101 | unsigned int maxvec; | ||
1102 | 1102 | ||
1103 | if (!(hpriv->flags & AHCI_HFLAG_NO_MSI)) { | 1103 | if (hpriv->flags & AHCI_HFLAG_NO_MSI) |
1104 | rc = pci_enable_msi_block_auto(pdev, &maxvec); | 1104 | goto intx; |
1105 | if (rc > 0) { | 1105 | |
1106 | if ((rc == maxvec) || (rc == 1)) | 1106 | rc = pci_msi_vec_count(pdev); |
1107 | return rc; | 1107 | if (rc < 0) |
1108 | /* | 1108 | goto intx; |
1109 | * Assume that advantage of multipe MSIs is negated, | 1109 | |
1110 | * so fallback to single MSI mode to save resources | 1110 | /* |
1111 | */ | 1111 | * If number of MSIs is less than number of ports then Sharing Last |
1112 | pci_disable_msi(pdev); | 1112 | * Message mode could be enforced. In this case assume that advantage |
1113 | if (!pci_enable_msi(pdev)) | 1113 | * of multipe MSIs is negated and use single MSI mode instead. |
1114 | return 1; | 1114 | */ |
1115 | } | 1115 | if (rc < n_ports) |
1116 | } | 1116 | goto single_msi; |
1117 | |||
1118 | nvec = rc; | ||
1119 | rc = pci_enable_msi_block(pdev, nvec); | ||
1120 | if (rc) | ||
1121 | goto intx; | ||
1117 | 1122 | ||
1123 | return nvec; | ||
1124 | |||
1125 | single_msi: | ||
1126 | rc = pci_enable_msi(pdev); | ||
1127 | if (rc) | ||
1128 | goto intx; | ||
1129 | return 1; | ||
1130 | |||
1131 | intx: | ||
1118 | pci_intx(pdev, 1); | 1132 | pci_intx(pdev, 1); |
1119 | return 0; | 1133 | return 0; |
1120 | } | 1134 | } |
@@ -1281,10 +1295,6 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1281 | 1295 | ||
1282 | hpriv->mmio = pcim_iomap_table(pdev)[ahci_pci_bar]; | 1296 | hpriv->mmio = pcim_iomap_table(pdev)[ahci_pci_bar]; |
1283 | 1297 | ||
1284 | n_msis = ahci_init_interrupts(pdev, hpriv); | ||
1285 | if (n_msis > 1) | ||
1286 | hpriv->flags |= AHCI_HFLAG_MULTI_MSI; | ||
1287 | |||
1288 | /* save initial config */ | 1298 | /* save initial config */ |
1289 | ahci_pci_save_initial_config(pdev, hpriv); | 1299 | ahci_pci_save_initial_config(pdev, hpriv); |
1290 | 1300 | ||
@@ -1339,6 +1349,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1339 | */ | 1349 | */ |
1340 | n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map)); | 1350 | n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map)); |
1341 | 1351 | ||
1352 | n_msis = ahci_init_interrupts(pdev, n_ports, hpriv); | ||
1353 | if (n_msis > 1) | ||
1354 | hpriv->flags |= AHCI_HFLAG_MULTI_MSI; | ||
1355 | |||
1342 | host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); | 1356 | host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); |
1343 | if (!host) | 1357 | if (!host) |
1344 | return -ENOMEM; | 1358 | return -ENOMEM; |
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 22957aa51edc..7a0fec6ce571 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -852,6 +852,31 @@ static int pci_msi_check_device(struct pci_dev *dev, int nvec, int type) | |||
852 | } | 852 | } |
853 | 853 | ||
854 | /** | 854 | /** |
855 | * pci_msi_vec_count - Return the number of MSI vectors a device can send | ||
856 | * @dev: device to report about | ||
857 | * | ||
858 | * This function returns the number of MSI vectors a device requested via | ||
859 | * Multiple Message Capable register. It returns a negative errno if the | ||
860 | * device is not capable sending MSI interrupts. Otherwise, the call succeeds | ||
861 | * and returns a power of two, up to a maximum of 2^5 (32), according to the | ||
862 | * MSI specification. | ||
863 | **/ | ||
864 | int pci_msi_vec_count(struct pci_dev *dev) | ||
865 | { | ||
866 | int ret; | ||
867 | u16 msgctl; | ||
868 | |||
869 | if (!dev->msi_cap) | ||
870 | return -EINVAL; | ||
871 | |||
872 | pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &msgctl); | ||
873 | ret = 1 << ((msgctl & PCI_MSI_FLAGS_QMASK) >> 1); | ||
874 | |||
875 | return ret; | ||
876 | } | ||
877 | EXPORT_SYMBOL(pci_msi_vec_count); | ||
878 | |||
879 | /** | ||
855 | * pci_enable_msi_block - configure device's MSI capability structure | 880 | * pci_enable_msi_block - configure device's MSI capability structure |
856 | * @dev: device to configure | 881 | * @dev: device to configure |
857 | * @nvec: number of interrupts to configure | 882 | * @nvec: number of interrupts to configure |
@@ -867,13 +892,13 @@ static int pci_msi_check_device(struct pci_dev *dev, int nvec, int type) | |||
867 | int pci_enable_msi_block(struct pci_dev *dev, int nvec) | 892 | int pci_enable_msi_block(struct pci_dev *dev, int nvec) |
868 | { | 893 | { |
869 | int status, maxvec; | 894 | int status, maxvec; |
870 | u16 msgctl; | ||
871 | 895 | ||
872 | if (!dev->msi_cap || dev->current_state != PCI_D0) | 896 | if (dev->current_state != PCI_D0) |
873 | return -EINVAL; | 897 | return -EINVAL; |
874 | 898 | ||
875 | pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &msgctl); | 899 | maxvec = pci_msi_vec_count(dev); |
876 | maxvec = 1 << ((msgctl & PCI_MSI_FLAGS_QMASK) >> 1); | 900 | if (maxvec < 0) |
901 | return maxvec; | ||
877 | if (nvec > maxvec) | 902 | if (nvec > maxvec) |
878 | return maxvec; | 903 | return maxvec; |
879 | 904 | ||
@@ -895,31 +920,6 @@ int pci_enable_msi_block(struct pci_dev *dev, int nvec) | |||
895 | } | 920 | } |
896 | EXPORT_SYMBOL(pci_enable_msi_block); | 921 | EXPORT_SYMBOL(pci_enable_msi_block); |
897 | 922 | ||
898 | int pci_enable_msi_block_auto(struct pci_dev *dev, int *maxvec) | ||
899 | { | ||
900 | int ret, nvec; | ||
901 | u16 msgctl; | ||
902 | |||
903 | if (!dev->msi_cap || dev->current_state != PCI_D0) | ||
904 | return -EINVAL; | ||
905 | |||
906 | pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &msgctl); | ||
907 | ret = 1 << ((msgctl & PCI_MSI_FLAGS_QMASK) >> 1); | ||
908 | |||
909 | if (maxvec) | ||
910 | *maxvec = ret; | ||
911 | |||
912 | do { | ||
913 | nvec = ret; | ||
914 | ret = pci_enable_msi_block(dev, nvec); | ||
915 | } while (ret > 0); | ||
916 | |||
917 | if (ret < 0) | ||
918 | return ret; | ||
919 | return nvec; | ||
920 | } | ||
921 | EXPORT_SYMBOL(pci_enable_msi_block_auto); | ||
922 | |||
923 | void pci_msi_shutdown(struct pci_dev *dev) | 923 | void pci_msi_shutdown(struct pci_dev *dev) |
924 | { | 924 | { |
925 | struct msi_desc *desc; | 925 | struct msi_desc *desc; |
@@ -957,19 +957,25 @@ void pci_disable_msi(struct pci_dev *dev) | |||
957 | EXPORT_SYMBOL(pci_disable_msi); | 957 | EXPORT_SYMBOL(pci_disable_msi); |
958 | 958 | ||
959 | /** | 959 | /** |
960 | * pci_msix_table_size - return the number of device's MSI-X table entries | 960 | * pci_msix_vec_count - return the number of device's MSI-X table entries |
961 | * @dev: pointer to the pci_dev data structure of MSI-X device function | 961 | * @dev: pointer to the pci_dev data structure of MSI-X device function |
962 | */ | 962 | |
963 | int pci_msix_table_size(struct pci_dev *dev) | 963 | * This function returns the number of device's MSI-X table entries and |
964 | * therefore the number of MSI-X vectors device is capable of sending. | ||
965 | * It returns a negative errno if the device is not capable of sending MSI-X | ||
966 | * interrupts. | ||
967 | **/ | ||
968 | int pci_msix_vec_count(struct pci_dev *dev) | ||
964 | { | 969 | { |
965 | u16 control; | 970 | u16 control; |
966 | 971 | ||
967 | if (!dev->msix_cap) | 972 | if (!dev->msix_cap) |
968 | return 0; | 973 | return -EINVAL; |
969 | 974 | ||
970 | pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control); | 975 | pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control); |
971 | return msix_table_size(control); | 976 | return msix_table_size(control); |
972 | } | 977 | } |
978 | EXPORT_SYMBOL(pci_msix_vec_count); | ||
973 | 979 | ||
974 | /** | 980 | /** |
975 | * pci_enable_msix - configure device's MSI-X capability structure | 981 | * pci_enable_msix - configure device's MSI-X capability structure |
@@ -998,7 +1004,9 @@ int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec) | |||
998 | if (status) | 1004 | if (status) |
999 | return status; | 1005 | return status; |
1000 | 1006 | ||
1001 | nr_entries = pci_msix_table_size(dev); | 1007 | nr_entries = pci_msix_vec_count(dev); |
1008 | if (nr_entries < 0) | ||
1009 | return nr_entries; | ||
1002 | if (nvec > nr_entries) | 1010 | if (nvec > nr_entries) |
1003 | return nr_entries; | 1011 | return nr_entries; |
1004 | 1012 | ||
@@ -1103,3 +1111,77 @@ void pci_msi_init_pci_dev(struct pci_dev *dev) | |||
1103 | if (dev->msix_cap) | 1111 | if (dev->msix_cap) |
1104 | msix_set_enable(dev, 0); | 1112 | msix_set_enable(dev, 0); |
1105 | } | 1113 | } |
1114 | |||
1115 | /** | ||
1116 | * pci_enable_msi_range - configure device's MSI capability structure | ||
1117 | * @dev: device to configure | ||
1118 | * @minvec: minimal number of interrupts to configure | ||
1119 | * @maxvec: maximum number of interrupts to configure | ||
1120 | * | ||
1121 | * This function tries to allocate a maximum possible number of interrupts in a | ||
1122 | * range between @minvec and @maxvec. It returns a negative errno if an error | ||
1123 | * occurs. If it succeeds, it returns the actual number of interrupts allocated | ||
1124 | * and updates the @dev's irq member to the lowest new interrupt number; | ||
1125 | * the other interrupt numbers allocated to this device are consecutive. | ||
1126 | **/ | ||
1127 | int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec) | ||
1128 | { | ||
1129 | int nvec = maxvec; | ||
1130 | int rc; | ||
1131 | |||
1132 | if (maxvec < minvec) | ||
1133 | return -ERANGE; | ||
1134 | |||
1135 | do { | ||
1136 | rc = pci_enable_msi_block(dev, nvec); | ||
1137 | if (rc < 0) { | ||
1138 | return rc; | ||
1139 | } else if (rc > 0) { | ||
1140 | if (rc < minvec) | ||
1141 | return -ENOSPC; | ||
1142 | nvec = rc; | ||
1143 | } | ||
1144 | } while (rc); | ||
1145 | |||
1146 | return nvec; | ||
1147 | } | ||
1148 | EXPORT_SYMBOL(pci_enable_msi_range); | ||
1149 | |||
1150 | /** | ||
1151 | * pci_enable_msix_range - configure device's MSI-X capability structure | ||
1152 | * @dev: pointer to the pci_dev data structure of MSI-X device function | ||
1153 | * @entries: pointer to an array of MSI-X entries | ||
1154 | * @minvec: minimum number of MSI-X irqs requested | ||
1155 | * @maxvec: maximum number of MSI-X irqs requested | ||
1156 | * | ||
1157 | * Setup the MSI-X capability structure of device function with a maximum | ||
1158 | * possible number of interrupts in the range between @minvec and @maxvec | ||
1159 | * upon its software driver call to request for MSI-X mode enabled on its | ||
1160 | * hardware device function. It returns a negative errno if an error occurs. | ||
1161 | * If it succeeds, it returns the actual number of interrupts allocated and | ||
1162 | * indicates the successful configuration of MSI-X capability structure | ||
1163 | * with new allocated MSI-X interrupts. | ||
1164 | **/ | ||
1165 | int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, | ||
1166 | int minvec, int maxvec) | ||
1167 | { | ||
1168 | int nvec = maxvec; | ||
1169 | int rc; | ||
1170 | |||
1171 | if (maxvec < minvec) | ||
1172 | return -ERANGE; | ||
1173 | |||
1174 | do { | ||
1175 | rc = pci_enable_msix(dev, entries, nvec); | ||
1176 | if (rc < 0) { | ||
1177 | return rc; | ||
1178 | } else if (rc > 0) { | ||
1179 | if (rc < minvec) | ||
1180 | return -ENOSPC; | ||
1181 | nvec = rc; | ||
1182 | } | ||
1183 | } while (rc); | ||
1184 | |||
1185 | return nvec; | ||
1186 | } | ||
1187 | EXPORT_SYMBOL(pci_enable_msix_range); | ||
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index 16a1ce4f6b18..986f8eadfd39 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c | |||
@@ -79,9 +79,10 @@ static int pcie_port_enable_msix(struct pci_dev *dev, int *vectors, int mask) | |||
79 | u16 reg16; | 79 | u16 reg16; |
80 | u32 reg32; | 80 | u32 reg32; |
81 | 81 | ||
82 | nr_entries = pci_msix_table_size(dev); | 82 | nr_entries = pci_msix_vec_count(dev); |
83 | if (!nr_entries) | 83 | if (nr_entries < 0) |
84 | return -EINVAL; | 84 | return nr_entries; |
85 | BUG_ON(!nr_entries); | ||
85 | if (nr_entries > PCIE_PORT_MAX_MSIX_ENTRIES) | 86 | if (nr_entries > PCIE_PORT_MAX_MSIX_ENTRIES) |
86 | nr_entries = PCIE_PORT_MAX_MSIX_ENTRIES; | 87 | nr_entries = PCIE_PORT_MAX_MSIX_ENTRIES; |
87 | 88 | ||
diff --git a/include/linux/pci.h b/include/linux/pci.h index 4b7cf4c954fe..b89069839020 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -1166,13 +1166,12 @@ struct msix_entry { | |||
1166 | 1166 | ||
1167 | 1167 | ||
1168 | #ifndef CONFIG_PCI_MSI | 1168 | #ifndef CONFIG_PCI_MSI |
1169 | static inline int pci_enable_msi_block(struct pci_dev *dev, int nvec) | 1169 | static inline int pci_msi_vec_count(struct pci_dev *dev) |
1170 | { | 1170 | { |
1171 | return -ENOSYS; | 1171 | return -ENOSYS; |
1172 | } | 1172 | } |
1173 | 1173 | ||
1174 | static inline int | 1174 | static inline int pci_enable_msi_block(struct pci_dev *dev, int nvec) |
1175 | pci_enable_msi_block_auto(struct pci_dev *dev, int *maxvec) | ||
1176 | { | 1175 | { |
1177 | return -ENOSYS; | 1176 | return -ENOSYS; |
1178 | } | 1177 | } |
@@ -1182,9 +1181,9 @@ static inline void pci_msi_shutdown(struct pci_dev *dev) | |||
1182 | static inline void pci_disable_msi(struct pci_dev *dev) | 1181 | static inline void pci_disable_msi(struct pci_dev *dev) |
1183 | { } | 1182 | { } |
1184 | 1183 | ||
1185 | static inline int pci_msix_table_size(struct pci_dev *dev) | 1184 | static inline int pci_msix_vec_count(struct pci_dev *dev) |
1186 | { | 1185 | { |
1187 | return 0; | 1186 | return -ENOSYS; |
1188 | } | 1187 | } |
1189 | static inline int pci_enable_msix(struct pci_dev *dev, | 1188 | static inline int pci_enable_msix(struct pci_dev *dev, |
1190 | struct msix_entry *entries, int nvec) | 1189 | struct msix_entry *entries, int nvec) |
@@ -1206,18 +1205,32 @@ static inline int pci_msi_enabled(void) | |||
1206 | { | 1205 | { |
1207 | return 0; | 1206 | return 0; |
1208 | } | 1207 | } |
1208 | |||
1209 | static inline int pci_enable_msi_range(struct pci_dev *dev, int minvec, | ||
1210 | int maxvec) | ||
1211 | { | ||
1212 | return -ENOSYS; | ||
1213 | } | ||
1214 | static inline int pci_enable_msix_range(struct pci_dev *dev, | ||
1215 | struct msix_entry *entries, int minvec, int maxvec) | ||
1216 | { | ||
1217 | return -ENOSYS; | ||
1218 | } | ||
1209 | #else | 1219 | #else |
1220 | int pci_msi_vec_count(struct pci_dev *dev); | ||
1210 | int pci_enable_msi_block(struct pci_dev *dev, int nvec); | 1221 | int pci_enable_msi_block(struct pci_dev *dev, int nvec); |
1211 | int pci_enable_msi_block_auto(struct pci_dev *dev, int *maxvec); | ||
1212 | void pci_msi_shutdown(struct pci_dev *dev); | 1222 | void pci_msi_shutdown(struct pci_dev *dev); |
1213 | void pci_disable_msi(struct pci_dev *dev); | 1223 | void pci_disable_msi(struct pci_dev *dev); |
1214 | int pci_msix_table_size(struct pci_dev *dev); | 1224 | int pci_msix_vec_count(struct pci_dev *dev); |
1215 | int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec); | 1225 | int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec); |
1216 | void pci_msix_shutdown(struct pci_dev *dev); | 1226 | void pci_msix_shutdown(struct pci_dev *dev); |
1217 | void pci_disable_msix(struct pci_dev *dev); | 1227 | void pci_disable_msix(struct pci_dev *dev); |
1218 | void msi_remove_pci_irq_vectors(struct pci_dev *dev); | 1228 | void msi_remove_pci_irq_vectors(struct pci_dev *dev); |
1219 | void pci_restore_msi_state(struct pci_dev *dev); | 1229 | void pci_restore_msi_state(struct pci_dev *dev); |
1220 | int pci_msi_enabled(void); | 1230 | int pci_msi_enabled(void); |
1231 | int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec); | ||
1232 | int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, | ||
1233 | int minvec, int maxvec); | ||
1221 | #endif | 1234 | #endif |
1222 | 1235 | ||
1223 | #ifdef CONFIG_PCIEPORTBUS | 1236 | #ifdef CONFIG_PCIEPORTBUS |