Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

PCI: Provide sensible IRQ vector alloc/free routines

Add a function to allocate and free a range of interrupt vectors, using
MSI-X, MSI or legacy vectors (in that order) based on the capabilities of
the underlying device and PCIe complex.

Additionally a new helper is provided to get the Linux IRQ number for given
device-relative vector so that the drivers don't need to allocate their own
arrays to keep track of the vectors for the multi vector MSI-X case.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Alexander Gordeev <agordeev@redhat.com>

authored by

Christoph Hellwig and committed by
Bjorn Helgaas
aff17164 3ac020e0

+203 -402
+87 -402
Documentation/PCI/MSI-HOWTO.txt
··· 78 78 79 79 4.2 Using MSI 80 80 81 - 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 81 + Most of the hard work is done for the driver in the PCI layer. The driver 82 + simply has to request that the PCI layer set up the MSI capability for this 83 83 device. 84 84 85 - 4.2.1 pci_enable_msi 85 + To automatically use MSI or MSI-X interrupt vectors, use the following 86 + function: 86 87 87 - int pci_enable_msi(struct pci_dev *dev) 88 + int pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs, 89 + unsigned int max_vecs, unsigned int flags); 88 90 89 - A successful call allocates ONE interrupt to the device, regardless 90 - of how many MSIs the device supports. The device is switched from 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. 91 + which allocates up to max_vecs interrupt vectors for a PCI device. It 92 + returns the number of vectors allocated or a negative error. If the device 93 + has a requirements for a minimum number of vectors the driver can pass a 94 + min_vecs argument set to this limit, and the PCI core will return -ENOSPC 95 + if it can't meet the minimum number of vectors. 96 96 97 - 4.2.2 pci_enable_msi_range 97 + The flags argument should normally be set to 0, but can be used to pass the 98 + PCI_IRQ_NOMSI and PCI_IRQ_NOMSIX flag in case a device claims to support 99 + MSI or MSI-X, but the support is broken, or to pass PCI_IRQ_NOLEGACY in 100 + case the device does not support legacy interrupt lines. 98 101 99 - int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec) 102 + To get the Linux IRQ numbers passed to request_irq() and free_irq() and the 103 + vectors, use the following function: 100 104 101 - This function allows a device driver to request any number of MSI 102 - interrupts within specified range from 'minvec' to 'maxvec'. 105 + int pci_irq_vector(struct pci_dev *dev, unsigned int nr); 103 106 104 - If this function returns a positive number it indicates the number of 105 - MSI interrupts that have been successfully allocated. In this case 106 - the device is switched from pin-based interrupt mode to MSI mode and 107 - updates dev->irq to be the lowest of the new interrupts assigned to it. 108 - The other interrupts assigned to the device are in the range dev->irq 109 - to dev->irq + returned value - 1. Device driver can use the returned 110 - number of successfully allocated MSI interrupts to further allocate 111 - and initialize device resources. 107 + Any allocated resources should be freed before removing the device using 108 + the following function: 112 109 113 - If this function returns a negative number, it indicates an error and 114 - the driver should not attempt to request any more MSI interrupts for 115 - this device. 110 + void pci_free_irq_vectors(struct pci_dev *dev); 116 111 117 - This function should be called before the driver calls request_irq(), 118 - because MSI interrupts are delivered via vectors that are different 119 - from the vector of a pin-based interrupt. 112 + If a device supports both MSI-X and MSI capabilities, this API will use the 113 + MSI-X facilities in preference to the MSI facilities. MSI-X supports any 114 + number of interrupts between 1 and 2048. In contrast, MSI is restricted to 115 + a maximum of 32 interrupts (and must be a power of two). In addition, the 116 + MSI interrupt vectors must be allocated consecutively, so the system might 117 + not be able to allocate as many vectors for MSI as it could for MSI-X. On 118 + some platforms, MSI interrupts must all be targeted at the same set of CPUs 119 + whereas MSI-X interrupts can all be targeted at different CPUs. 120 120 121 - It is ideal if drivers can cope with a variable number of MSI interrupts; 122 - there are many reasons why the platform may not be able to provide the 123 - exact number that a driver asks for. 121 + If a device supports neither MSI-X or MSI it will fall back to a single 122 + legacy IRQ vector. 124 123 125 - There could be devices that can not operate with just any number of MSI 126 - interrupts within a range. See chapter 4.3.1.3 to get the idea how to 127 - handle such devices for MSI-X - the same logic applies to MSI. 124 + The typical usage of MSI or MSI-X interrupts is to allocate as many vectors 125 + as possible, likely up to the limit supported by the device. If nvec is 126 + larger than the number supported by the device it will automatically be 127 + capped to the supported limit, so there is no need to query the number of 128 + vectors supported beforehand: 128 129 129 - 4.2.1.1 Maximum possible number of MSI interrupts 130 - 131 - The typical usage of MSI interrupts is to allocate as many vectors as 132 - possible, likely up to the limit returned by pci_msi_vec_count() function: 133 - 134 - static int foo_driver_enable_msi(struct pci_dev *pdev, int nvec) 135 - { 136 - return pci_enable_msi_range(pdev, 1, nvec); 137 - } 138 - 139 - Note the value of 'minvec' parameter is 1. As 'minvec' is inclusive, 140 - the value of 0 would be meaningless and could result in error. 141 - 142 - Some devices have a minimal limit on number of MSI interrupts. 143 - In this case the function could look like this: 144 - 145 - static int foo_driver_enable_msi(struct pci_dev *pdev, int nvec) 146 - { 147 - return pci_enable_msi_range(pdev, FOO_DRIVER_MINIMUM_NVEC, nvec); 148 - } 149 - 150 - 4.2.1.2 Exact number of MSI interrupts 130 + nvec = pci_alloc_irq_vectors(pdev, 1, nvec, 0); 131 + if (nvec < 0) 132 + goto out_err; 151 133 152 134 If a driver is unable or unwilling to deal with a variable number of MSI 153 - interrupts it could request a particular number of interrupts by passing 154 - that number to pci_enable_msi_range() function as both 'minvec' and 'maxvec' 155 - parameters: 156 - 157 - static int foo_driver_enable_msi(struct pci_dev *pdev, int nvec) 158 - { 159 - return pci_enable_msi_range(pdev, nvec, nvec); 160 - } 161 - 162 - Note, unlike pci_enable_msi_exact() function, which could be also used to 163 - enable a particular number of MSI-X interrupts, pci_enable_msi_range() 164 - returns either a negative errno or 'nvec' (not negative errno or 0 - as 165 - pci_enable_msi_exact() does). 166 - 167 - 4.2.1.3 Single MSI mode 168 - 169 - The most notorious example of the request type described above is 170 - enabling the single MSI mode for a device. It could be done by passing 171 - two 1s as 'minvec' and 'maxvec': 172 - 173 - static int foo_driver_enable_single_msi(struct pci_dev *pdev) 174 - { 175 - return pci_enable_msi_range(pdev, 1, 1); 176 - } 177 - 178 - Note, unlike pci_enable_msi() function, which could be also used to 179 - enable the single MSI mode, pci_enable_msi_range() returns either a 180 - negative errno or 1 (not negative errno or 0 - as pci_enable_msi() 181 - does). 182 - 183 - 4.2.3 pci_enable_msi_exact 184 - 185 - int pci_enable_msi_exact(struct pci_dev *dev, int nvec) 186 - 187 - This variation on pci_enable_msi_range() call allows a device driver to 188 - request exactly 'nvec' MSIs. 189 - 190 - If this function returns a negative number, it indicates an error and 191 - the driver should not attempt to request any more MSI interrupts for 192 - this device. 193 - 194 - By contrast with pci_enable_msi_range() function, pci_enable_msi_exact() 195 - returns zero in case of success, which indicates MSI interrupts have been 196 - successfully allocated. 197 - 198 - 4.2.4 pci_disable_msi 199 - 200 - void pci_disable_msi(struct pci_dev *dev) 201 - 202 - This function should be used to undo the effect of pci_enable_msi_range(). 203 - Calling it restores dev->irq to the pin-based interrupt number and frees 204 - the previously allocated MSIs. The interrupts may subsequently be assigned 205 - to another device, so drivers should not cache the value of dev->irq. 206 - 207 - Before calling this function, a device driver must always call free_irq() 208 - on any interrupt for which it previously called request_irq(). 209 - Failure to do so results in a BUG_ON(), leaving the device with 210 - MSI enabled and thus leaking its vector. 211 - 212 - 4.2.4 pci_msi_vec_count 213 - 214 - int pci_msi_vec_count(struct pci_dev *dev) 215 - 216 - This function could be used to retrieve the number of MSI vectors the 217 - device requested (via the Multiple Message Capable register). The MSI 218 - specification only allows the returned value to be a power of two, 219 - up to a maximum of 2^5 (32). 220 - 221 - If this function returns a negative number, it indicates the device is 222 - not capable of sending MSIs. 223 - 224 - If this function returns a positive number, it indicates the maximum 225 - number of MSI interrupt vectors that could be allocated. 226 - 227 - 4.3 Using MSI-X 228 - 229 - The MSI-X capability is much more flexible than the MSI capability. 230 - It supports up to 2048 interrupts, each of which can be controlled 231 - independently. To support this flexibility, drivers must use an array of 232 - `struct msix_entry': 233 - 234 - struct msix_entry { 235 - u16 vector; /* kernel uses to write alloc vector */ 236 - u16 entry; /* driver uses to specify entry */ 237 - }; 238 - 239 - This allows for the device to use these interrupts in a sparse fashion; 240 - for example, it could use interrupts 3 and 1027 and yet allocate only a 241 - two-element array. The driver is expected to fill in the 'entry' value 242 - in each element of the array to indicate for which entries the kernel 243 - should assign interrupts; it is invalid to fill in two entries with the 244 - same number. 245 - 246 - 4.3.1 pci_enable_msix_range 247 - 248 - int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, 249 - int minvec, int maxvec) 250 - 251 - Calling this function asks the PCI subsystem to allocate any number of 252 - MSI-X interrupts within specified range from 'minvec' to 'maxvec'. 253 - The 'entries' argument is a pointer to an array of msix_entry structs 254 - which should be at least 'maxvec' entries in size. 255 - 256 - On success, the device is switched into MSI-X mode and the function 257 - returns the number of MSI-X interrupts that have been successfully 258 - allocated. In this case the 'vector' member in entries numbered from 259 - 0 to the returned value - 1 is populated with the interrupt number; 260 - the driver should then call request_irq() for each 'vector' that it 261 - decides to use. The device driver is responsible for keeping track of the 262 - interrupts assigned to the MSI-X vectors so it can free them again later. 263 - Device driver can use the returned number of successfully allocated MSI-X 264 - interrupts to further allocate and initialize device resources. 265 - 266 - If this function returns a negative number, it indicates an error and 267 - the driver should not attempt to allocate any more MSI-X interrupts for 268 - this device. 269 - 270 - This function, in contrast with pci_enable_msi_range(), does not adjust 271 - dev->irq. The device will not generate interrupts for this interrupt 272 - number once MSI-X is enabled. 273 - 274 - Device drivers should normally call this function once per device 275 - during the initialization phase. 276 - 277 - It is ideal if drivers can cope with a variable number of MSI-X interrupts; 278 - there are many reasons why the platform may not be able to provide the 279 - exact number that a driver asks for. 280 - 281 - There could be devices that can not operate with just any number of MSI-X 282 - interrupts within a range. E.g., an network adapter might need let's say 283 - four vectors per each queue it provides. Therefore, a number of MSI-X 284 - interrupts allocated should be a multiple of four. In this case interface 285 - pci_enable_msix_range() can not be used alone to request MSI-X interrupts 286 - (since it can allocate any number within the range, without any notion of 287 - the multiple of four) and the device driver should master a custom logic 288 - to request the required number of MSI-X interrupts. 289 - 290 - 4.3.1.1 Maximum possible number of MSI-X interrupts 291 - 292 - The typical usage of MSI-X interrupts is to allocate as many vectors as 293 - possible, likely up to the limit returned by pci_msix_vec_count() function: 294 - 295 - static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec) 296 - { 297 - return pci_enable_msix_range(adapter->pdev, adapter->msix_entries, 298 - 1, nvec); 299 - } 300 - 301 - Note the value of 'minvec' parameter is 1. As 'minvec' is inclusive, 302 - the value of 0 would be meaningless and could result in error. 303 - 304 - Some devices have a minimal limit on number of MSI-X interrupts. 305 - In this case the function could look like this: 306 - 307 - static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec) 308 - { 309 - return pci_enable_msix_range(adapter->pdev, adapter->msix_entries, 310 - FOO_DRIVER_MINIMUM_NVEC, nvec); 311 - } 312 - 313 - 4.3.1.2 Exact number of MSI-X interrupts 314 - 315 - If a driver is unable or unwilling to deal with a variable number of MSI-X 316 - interrupts it could request a particular number of interrupts by passing 317 - that number to pci_enable_msix_range() function as both 'minvec' and 'maxvec' 318 - parameters: 319 - 320 - static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec) 321 - { 322 - return pci_enable_msix_range(adapter->pdev, adapter->msix_entries, 323 - nvec, nvec); 324 - } 325 - 326 - Note, unlike pci_enable_msix_exact() function, which could be also used to 327 - enable a particular number of MSI-X interrupts, pci_enable_msix_range() 328 - returns either a negative errno or 'nvec' (not negative errno or 0 - as 329 - pci_enable_msix_exact() does). 330 - 331 - 4.3.1.3 Specific requirements to the number of MSI-X interrupts 332 - 333 - As noted above, there could be devices that can not operate with just any 334 - number of MSI-X interrupts within a range. E.g., let's assume a device that 335 - is only capable sending the number of MSI-X interrupts which is a power of 336 - two. A routine that enables MSI-X mode for such device might look like this: 337 - 338 - /* 339 - * Assume 'minvec' and 'maxvec' are non-zero 340 - */ 341 - static int foo_driver_enable_msix(struct foo_adapter *adapter, 342 - int minvec, int maxvec) 343 - { 344 - int rc; 345 - 346 - minvec = roundup_pow_of_two(minvec); 347 - maxvec = rounddown_pow_of_two(maxvec); 348 - 349 - if (minvec > maxvec) 350 - return -ERANGE; 351 - 352 - retry: 353 - rc = pci_enable_msix_range(adapter->pdev, adapter->msix_entries, 354 - maxvec, maxvec); 355 - /* 356 - * -ENOSPC is the only error code allowed to be analyzed 357 - */ 358 - if (rc == -ENOSPC) { 359 - if (maxvec == 1) 360 - return -ENOSPC; 361 - 362 - maxvec /= 2; 363 - 364 - if (minvec > maxvec) 365 - return -ENOSPC; 366 - 367 - goto retry; 368 - } 369 - 370 - return rc; 371 - } 372 - 373 - Note how pci_enable_msix_range() return value is analyzed for a fallback - 374 - any error code other than -ENOSPC indicates a fatal error and should not 375 - be retried. 376 - 377 - 4.3.2 pci_enable_msix_exact 378 - 379 - int pci_enable_msix_exact(struct pci_dev *dev, 380 - struct msix_entry *entries, int nvec) 381 - 382 - This variation on pci_enable_msix_range() call allows a device driver to 383 - request exactly 'nvec' MSI-Xs. 384 - 385 - If this function returns a negative number, it indicates an error and 386 - the driver should not attempt to allocate any more MSI-X interrupts for 387 - this device. 388 - 389 - By contrast with pci_enable_msix_range() function, pci_enable_msix_exact() 390 - returns zero in case of success, which indicates MSI-X interrupts have been 391 - successfully allocated. 392 - 393 - Another version of a routine that enables MSI-X mode for a device with 394 - specific requirements described in chapter 4.3.1.3 might look like this: 395 - 396 - /* 397 - * Assume 'minvec' and 'maxvec' are non-zero 398 - */ 399 - static int foo_driver_enable_msix(struct foo_adapter *adapter, 400 - int minvec, int maxvec) 401 - { 402 - int rc; 403 - 404 - minvec = roundup_pow_of_two(minvec); 405 - maxvec = rounddown_pow_of_two(maxvec); 406 - 407 - if (minvec > maxvec) 408 - return -ERANGE; 409 - 410 - retry: 411 - rc = pci_enable_msix_exact(adapter->pdev, 412 - adapter->msix_entries, maxvec); 413 - 414 - /* 415 - * -ENOSPC is the only error code allowed to be analyzed 416 - */ 417 - if (rc == -ENOSPC) { 418 - if (maxvec == 1) 419 - return -ENOSPC; 420 - 421 - maxvec /= 2; 422 - 423 - if (minvec > maxvec) 424 - return -ENOSPC; 425 - 426 - goto retry; 427 - } else if (rc < 0) { 428 - return rc; 429 - } 430 - 431 - return maxvec; 432 - } 433 - 434 - 4.3.3 pci_disable_msix 435 - 436 - void pci_disable_msix(struct pci_dev *dev) 437 - 438 - This function should be used to undo the effect of pci_enable_msix_range(). 439 - It frees the previously allocated MSI-X interrupts. The interrupts may 440 - subsequently be assigned to another device, so drivers should not cache 441 - the value of the 'vector' elements over a call to pci_disable_msix(). 442 - 443 - Before calling this function, a device driver must always call free_irq() 444 - on any interrupt for which it previously called request_irq(). 445 - Failure to do so results in a BUG_ON(), leaving the device with 446 - MSI-X enabled and thus leaking its vector. 447 - 448 - 4.3.3 The MSI-X Table 449 - 450 - The MSI-X capability specifies a BAR and offset within that BAR for the 451 - MSI-X Table. This address is mapped by the PCI subsystem, and should not 452 - be accessed directly by the device driver. If the driver wishes to 453 - mask or unmask an interrupt, it should call disable_irq() / enable_irq(). 454 - 455 - 4.3.4 pci_msix_vec_count 456 - 457 - int pci_msix_vec_count(struct pci_dev *dev) 458 - 459 - This function could be used to retrieve number of entries in the device 460 - MSI-X table. 461 - 462 - If this function returns a negative number, it indicates the device is 463 - not capable of sending MSI-Xs. 464 - 465 - If this function returns a positive number, it indicates the maximum 466 - number of MSI-X interrupt vectors that could be allocated. 467 - 468 - 4.4 Handling devices implementing both MSI and MSI-X capabilities 469 - 470 - If a device implements both MSI and MSI-X capabilities, it can 471 - run in either MSI mode or MSI-X mode, but not both simultaneously. 472 - This is a requirement of the PCI spec, and it is enforced by the 473 - PCI layer. Calling pci_enable_msi_range() when MSI-X is already 474 - enabled or pci_enable_msix_range() when MSI is already enabled 475 - results in an error. If a device driver wishes to switch between MSI 476 - and MSI-X at runtime, it must first quiesce the device, then switch 477 - it back to pin-interrupt mode, before calling pci_enable_msi_range() 478 - or pci_enable_msix_range() and resuming operation. This is not expected 479 - to be a common operation but may be useful for debugging or testing 480 - during development. 481 - 482 - 4.5 Considerations when using MSIs 483 - 484 - 4.5.1 Choosing between MSI-X and MSI 485 - 486 - If your device supports both MSI-X and MSI capabilities, you should use 487 - the MSI-X facilities in preference to the MSI facilities. As mentioned 488 - above, MSI-X supports any number of interrupts between 1 and 2048. 489 - In contrast, MSI is restricted to a maximum of 32 interrupts (and 490 - must be a power of two). In addition, the MSI interrupt vectors must 491 - be allocated consecutively, so the system might not be able to allocate 492 - as many vectors for MSI as it could for MSI-X. On some platforms, MSI 493 - interrupts must all be targeted at the same set of CPUs whereas MSI-X 494 - interrupts can all be targeted at different CPUs. 495 - 496 - 4.5.2 Spinlocks 135 + interrupts it can request a particular number of interrupts by passing that 136 + number to pci_alloc_irq_vectors() function as both 'min_vecs' and 137 + 'max_vecs' parameters: 138 + 139 + ret = pci_alloc_irq_vectors(pdev, nvec, nvec, 0); 140 + if (ret < 0) 141 + goto out_err; 142 + 143 + The most notorious example of the request type described above is enabling 144 + the single MSI mode for a device. It could be done by passing two 1s as 145 + 'min_vecs' and 'max_vecs': 146 + 147 + ret = pci_alloc_irq_vectors(pdev, 1, 1, 0); 148 + if (ret < 0) 149 + goto out_err; 150 + 151 + Some devices might not support using legacy line interrupts, in which case 152 + the PCI_IRQ_NOLEGACY flag can be used to fail the request if the platform 153 + can't provide MSI or MSI-X interrupts: 154 + 155 + nvec = pci_alloc_irq_vectors(pdev, 1, nvec, PCI_IRQ_NOLEGACY); 156 + if (nvec < 0) 157 + goto out_err; 158 + 159 + 4.3 Legacy APIs 160 + 161 + The following old APIs to enable and disable MSI or MSI-X interrupts should 162 + not be used in new code: 163 + 164 + pci_enable_msi() /* deprecated */ 165 + pci_enable_msi_range() /* deprecated */ 166 + pci_enable_msi_exact() /* deprecated */ 167 + pci_disable_msi() /* deprecated */ 168 + pci_enable_msix_range() /* deprecated */ 169 + pci_enable_msix_exact() /* deprecated */ 170 + pci_disable_msix() /* deprecated */ 171 + 172 + Additionally there are APIs to provide the number of supported MSI or MSI-X 173 + vectors: pci_msi_vec_count() and pci_msix_vec_count(). In general these 174 + should be avoided in favor of letting pci_alloc_irq_vectors() cap the 175 + number of vectors. If you have a legitimate special use case for the count 176 + of vectors we might have to revisit that decision and add a 177 + pci_nr_irq_vectors() helper that handles MSI and MSI-X transparently. 178 + 179 + 4.4 Considerations when using MSIs 180 + 181 + 4.4.1 Spinlocks 497 182 498 183 Most device drivers have a per-device spinlock which is taken in the 499 184 interrupt handler. With pin-based interrupts or a single MSI, it is not ··· 190 505 spin_lock_irqsave() or spin_lock_irq() which disable local interrupts 191 506 and acquire the lock (see Documentation/DocBook/kernel-locking). 192 507 193 - 4.6 How to tell whether MSI/MSI-X is enabled on a device 508 + 4.5 How to tell whether MSI/MSI-X is enabled on a device 194 509 195 510 Using 'lspci -v' (as root) may show some devices with "MSI", "Message 196 511 Signalled Interrupts" or "MSI-X" capabilities. Each of these capabilities
+89
drivers/pci/msi.c
··· 4 4 * 5 5 * Copyright (C) 2003-2004 Intel 6 6 * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com) 7 + * Copyright (C) 2016 Christoph Hellwig. 7 8 */ 8 9 9 10 #include <linux/err.h> ··· 1121 1120 return nvec; 1122 1121 } 1123 1122 EXPORT_SYMBOL(pci_enable_msix_range); 1123 + 1124 + /** 1125 + * pci_alloc_irq_vectors - allocate multiple IRQs for a device 1126 + * @dev: PCI device to operate on 1127 + * @min_vecs: minimum number of vectors required (must be >= 1) 1128 + * @max_vecs: maximum (desired) number of vectors 1129 + * @flags: flags or quirks for the allocation 1130 + * 1131 + * Allocate up to @max_vecs interrupt vectors for @dev, using MSI-X or MSI 1132 + * vectors if available, and fall back to a single legacy vector 1133 + * if neither is available. Return the number of vectors allocated, 1134 + * (which might be smaller than @max_vecs) if successful, or a negative 1135 + * error code on error. If less than @min_vecs interrupt vectors are 1136 + * available for @dev the function will fail with -ENOSPC. 1137 + * 1138 + * To get the Linux IRQ number used for a vector that can be passed to 1139 + * request_irq() use the pci_irq_vector() helper. 1140 + */ 1141 + int pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs, 1142 + unsigned int max_vecs, unsigned int flags) 1143 + { 1144 + int vecs = -ENOSPC; 1145 + 1146 + if (!(flags & PCI_IRQ_NOMSIX)) { 1147 + vecs = pci_enable_msix_range(dev, NULL, min_vecs, max_vecs); 1148 + if (vecs > 0) 1149 + return vecs; 1150 + } 1151 + 1152 + if (!(flags & PCI_IRQ_NOMSI)) { 1153 + vecs = pci_enable_msi_range(dev, min_vecs, max_vecs); 1154 + if (vecs > 0) 1155 + return vecs; 1156 + } 1157 + 1158 + /* use legacy irq if allowed */ 1159 + if (!(flags & PCI_IRQ_NOLEGACY) && min_vecs == 1) 1160 + return 1; 1161 + return vecs; 1162 + } 1163 + EXPORT_SYMBOL(pci_alloc_irq_vectors); 1164 + 1165 + /** 1166 + * pci_free_irq_vectors - free previously allocated IRQs for a device 1167 + * @dev: PCI device to operate on 1168 + * 1169 + * Undoes the allocations and enabling in pci_alloc_irq_vectors(). 1170 + */ 1171 + void pci_free_irq_vectors(struct pci_dev *dev) 1172 + { 1173 + pci_disable_msix(dev); 1174 + pci_disable_msi(dev); 1175 + } 1176 + EXPORT_SYMBOL(pci_free_irq_vectors); 1177 + 1178 + /** 1179 + * pci_irq_vector - return Linux IRQ number of a device vector 1180 + * @dev: PCI device to operate on 1181 + * @nr: device-relative interrupt vector index (0-based). 1182 + */ 1183 + int pci_irq_vector(struct pci_dev *dev, unsigned int nr) 1184 + { 1185 + if (dev->msix_enabled) { 1186 + struct msi_desc *entry; 1187 + int i = 0; 1188 + 1189 + for_each_pci_msi_entry(entry, dev) { 1190 + if (i == nr) 1191 + return entry->irq; 1192 + i++; 1193 + } 1194 + WARN_ON_ONCE(1); 1195 + return -EINVAL; 1196 + } 1197 + 1198 + if (dev->msi_enabled) { 1199 + struct msi_desc *entry = first_pci_msi_entry(dev); 1200 + 1201 + if (WARN_ON_ONCE(nr >= entry->nvec_used)) 1202 + return -EINVAL; 1203 + } else { 1204 + if (WARN_ON_ONCE(nr > 0)) 1205 + return -EINVAL; 1206 + } 1207 + 1208 + return dev->irq + nr; 1209 + } 1210 + EXPORT_SYMBOL(pci_irq_vector); 1124 1211 1125 1212 struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc) 1126 1213 {
+27
include/linux/pci.h
··· 1237 1237 int pci_set_vga_state(struct pci_dev *pdev, bool decode, 1238 1238 unsigned int command_bits, u32 flags); 1239 1239 1240 + #define PCI_IRQ_NOLEGACY (1 << 0) /* don't use legacy interrupts */ 1241 + #define PCI_IRQ_NOMSI (1 << 1) /* don't use MSI interrupts */ 1242 + #define PCI_IRQ_NOMSIX (1 << 2) /* don't use MSI-X interrupts */ 1243 + 1240 1244 /* kmem_cache style wrapper around pci_alloc_consistent() */ 1241 1245 1242 1246 #include <linux/pci-dma.h> ··· 1288 1284 return rc; 1289 1285 return 0; 1290 1286 } 1287 + int pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs, 1288 + unsigned int max_vecs, unsigned int flags); 1289 + void pci_free_irq_vectors(struct pci_dev *dev); 1290 + int pci_irq_vector(struct pci_dev *dev, unsigned int nr); 1291 + 1291 1292 #else 1292 1293 static inline int pci_msi_vec_count(struct pci_dev *dev) { return -ENOSYS; } 1293 1294 static inline void pci_msi_shutdown(struct pci_dev *dev) { } ··· 1316 1307 static inline int pci_enable_msix_exact(struct pci_dev *dev, 1317 1308 struct msix_entry *entries, int nvec) 1318 1309 { return -ENOSYS; } 1310 + static inline int pci_alloc_irq_vectors(struct pci_dev *dev, 1311 + unsigned int min_vecs, unsigned int max_vecs, 1312 + unsigned int flags) 1313 + { 1314 + if (min_vecs > 1) 1315 + return -EINVAL; 1316 + return 1; 1317 + } 1318 + static inline void pci_free_irq_vectors(struct pci_dev *dev) 1319 + { 1320 + } 1321 + 1322 + static inline int pci_irq_vector(struct pci_dev *dev, unsigned int nr) 1323 + { 1324 + if (WARN_ON_ONCE(nr > 0)) 1325 + return -EINVAL; 1326 + return dev->irq; 1327 + } 1319 1328 #endif 1320 1329 1321 1330 #ifdef CONFIG_PCIEPORTBUS