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

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()

+386 -164
+211 -99
Documentation/PCI/MSI-HOWTO.txt
··· 82 82 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 + 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 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. 89 + This function allows a device driver to request any number of MSI 90 + interrupts within specified range from 'minvec' to 'maxvec'. 96 91 97 - 4.2.2 pci_enable_msi_block 98 - 99 - int pci_enable_msi_block(struct pci_dev *dev, int count) 100 - 101 - This variation on the above call allows a device driver to request multiple 102 - MSIs. The MSI specification only allows interrupts to be allocated in 103 - powers of two, up to a maximum of 2^5 (32). 104 - 105 - If this function returns 0, it has succeeded in allocating at least as many 106 - interrupts as the driver requested (it may have allocated more in order 107 - to satisfy the power-of-two requirement). In this case, the function 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 - If this function returns a negative number, it indicates an error and 113 - the driver should not attempt to request any more MSI interrupts for 114 - this device. If this function returns a positive number, it is 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. 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. 144 100 145 101 If this function returns a negative number, it indicates an error and 146 102 the driver should not attempt to request any more MSI interrupts for 147 103 this device. 148 104 149 - If the device driver needs to know the number of interrupts the device 150 - supports it can pass the pointer count where that number is stored. The 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. 105 + This function should be called before the driver calls request_irq(), 106 + because MSI interrupts are delivered via vectors that are different 107 + from the vector of a pin-based interrupt. 155 108 156 - 4.2.4 pci_disable_msi 109 + It is ideal if drivers can cope with a variable number of MSI interrupts; 110 + there are many reasons why the platform may not be able to provide the 111 + exact number that a driver asks for. 112 + 113 + There could be devices that can not operate with just any number of MSI 114 + interrupts within a range. See chapter 4.3.1.3 to get the idea how to 115 + handle such devices for MSI-X - the same logic applies to MSI. 116 + 117 + 4.2.1.1 Maximum possible number of MSI interrupts 118 + 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. 129 + 130 + Some devices have a minimal limit on number of MSI interrupts. 131 + In this case the function could look like this: 132 + 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 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 161 - pci_enable_msi_block() or pci_enable_msi_block_auto(). Calling it restores 162 - dev->irq to the pin-based interrupt number and frees the previously 163 - allocated message signaled interrupt(s). The interrupt may subsequently be 164 - assigned to another device, so drivers should not cache the value of 165 - dev->irq. 165 + This function should be used to undo the effect of pci_enable_msi_range(). 166 + Calling it restores dev->irq to the pin-based interrupt number and frees 167 + the previously allocated MSIs. The interrupts may subsequently be assigned 168 + to another device, so drivers should not cache the value of dev->irq. 166 169 167 170 Before calling this function, a device driver must always call free_irq() 168 171 on any interrupt for which it previously called request_irq(). 169 172 Failure to do so results in a BUG_ON(), leaving the device with 170 173 MSI enabled and thus leaking its vector. 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. 171 189 172 190 4.3 Using MSI-X 173 191 ··· 206 188 should assign interrupts; it is invalid to fill in two entries with the 207 189 same number. 208 190 209 - 4.3.1 pci_enable_msix 191 + 4.3.1 pci_enable_msix_range 210 192 211 - int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec) 193 + int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, 194 + int minvec, int maxvec) 212 195 213 - Calling this function asks the PCI subsystem to allocate 'nvec' MSIs. 196 + Calling this function asks the PCI subsystem to allocate any number of 197 + MSI-X interrupts within specified range from 'minvec' to 'maxvec'. 214 198 The 'entries' argument is a pointer to an array of msix_entry structs 215 - which should be at least 'nvec' entries in size. On success, the 216 - device is switched into MSI-X mode and the function returns 0. 217 - The 'vector' member in each entry is populated with the interrupt number; 199 + which should be at least 'maxvec' entries in size. 200 + 201 + On success, the device is switched into MSI-X mode and the function 202 + returns the number of MSI-X interrupts that have been successfully 203 + allocated. In this case the 'vector' member in entries numbered from 204 + 0 to the returned value - 1 is populated with the interrupt number; 218 205 the driver should then call request_irq() for each 'vector' that it 219 206 decides to use. The device driver is responsible for keeping track of the 220 207 interrupts assigned to the MSI-X vectors so it can free them again later. 208 + Device driver can use the returned number of successfully allocated MSI-X 209 + interrupts to further allocate and initialize device resources. 221 210 222 211 If this function returns a negative number, it indicates an error and 223 212 the driver should not attempt to allocate any more MSI-X interrupts for 224 - this device. If it returns a positive number, it indicates the maximum 225 - number of interrupt vectors that could have been allocated. See example 226 - below. 213 + this device. 227 214 228 - This function, in contrast with pci_enable_msi(), does not adjust 215 + This function, in contrast with pci_enable_msi_range(), does not adjust 229 216 dev->irq. The device will not generate interrupts for this interrupt 230 217 number once MSI-X is enabled. 231 218 ··· 241 218 there are many reasons why the platform may not be able to provide the 242 219 exact number that a driver asks for. 243 220 244 - A request loop to achieve that might look like: 221 + There could be devices that can not operate with just any number of MSI-X 222 + interrupts within a range. E.g., an network adapter might need let's say 223 + four vectors per each queue it provides. Therefore, a number of MSI-X 224 + interrupts allocated should be a multiple of four. In this case interface 225 + pci_enable_msix_range() can not be used alone to request MSI-X interrupts 226 + (since it can allocate any number within the range, without any notion of 227 + the multiple of four) and the device driver should master a custom logic 228 + to request the required number of MSI-X interrupts. 229 + 230 + 4.3.1.1 Maximum possible number of MSI-X interrupts 231 + 232 + The typical usage of MSI-X interrupts is to allocate as many vectors as 233 + possible, likely up to the limit returned by pci_msix_vec_count() function: 245 234 246 235 static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec) 247 236 { 248 - while (nvec >= FOO_DRIVER_MINIMUM_NVEC) { 249 - rc = pci_enable_msix(adapter->pdev, 250 - adapter->msix_entries, nvec); 251 - if (rc > 0) 252 - nvec = rc; 253 - else 254 - return rc; 237 + return pci_enable_msi_range(adapter->pdev, adapter->msix_entries, 238 + 1, nvec); 239 + } 240 + 241 + Note the value of 'minvec' parameter is 1. As 'minvec' is inclusive, 242 + the value of 0 would be meaningless and could result in error. 243 + 244 + Some devices have a minimal limit on number of MSI-X interrupts. 245 + In this case the function could look like this: 246 + 247 + static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec) 248 + { 249 + return pci_enable_msi_range(adapter->pdev, adapter->msix_entries, 250 + FOO_DRIVER_MINIMUM_NVEC, nvec); 251 + } 252 + 253 + 4.3.1.2 Exact number of MSI-X interrupts 254 + 255 + If a driver is unable or unwilling to deal with a variable number of MSI-X 256 + interrupts it could request a particular number of interrupts by passing 257 + that number to pci_enable_msix_range() function as both 'minvec' and 'maxvec' 258 + parameters: 259 + 260 + static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec) 261 + { 262 + return pci_enable_msi_range(adapter->pdev, adapter->msix_entries, 263 + nvec, nvec); 264 + } 265 + 266 + 4.3.1.3 Specific requirements to the number of MSI-X interrupts 267 + 268 + As noted above, there could be devices that can not operate with just any 269 + number of MSI-X interrupts within a range. E.g., let's assume a device that 270 + is only capable sending the number of MSI-X interrupts which is a power of 271 + two. A routine that enables MSI-X mode for such device might look like this: 272 + 273 + /* 274 + * Assume 'minvec' and 'maxvec' are non-zero 275 + */ 276 + static int foo_driver_enable_msix(struct foo_adapter *adapter, 277 + int minvec, int maxvec) 278 + { 279 + int rc; 280 + 281 + minvec = roundup_pow_of_two(minvec); 282 + maxvec = rounddown_pow_of_two(maxvec); 283 + 284 + if (minvec > maxvec) 285 + return -ERANGE; 286 + 287 + retry: 288 + rc = pci_enable_msix_range(adapter->pdev, adapter->msix_entries, 289 + maxvec, maxvec); 290 + /* 291 + * -ENOSPC is the only error code allowed to be analized 292 + */ 293 + if (rc == -ENOSPC) { 294 + if (maxvec == 1) 295 + return -ENOSPC; 296 + 297 + maxvec /= 2; 298 + 299 + if (minvec > maxvec) 300 + return -ENOSPC; 301 + 302 + goto retry; 255 303 } 256 304 257 - return -ENOSPC; 305 + return rc; 258 306 } 307 + 308 + Note how pci_enable_msix_range() return value is analized for a fallback - 309 + any error code other than -ENOSPC indicates a fatal error and should not 310 + be retried. 259 311 260 312 4.3.2 pci_disable_msix 261 313 262 314 void pci_disable_msix(struct pci_dev *dev) 263 315 264 - This function should be used to undo the effect of pci_enable_msix(). It frees 265 - the previously allocated message signaled interrupts. The interrupts may 316 + This function should be used to undo the effect of pci_enable_msix_range(). 317 + It frees the previously allocated MSI-X interrupts. The interrupts may 266 318 subsequently be assigned to another device, so drivers should not cache 267 319 the value of the 'vector' elements over a call to pci_disable_msix(). 268 320 ··· 353 255 be accessed directly by the device driver. If the driver wishes to 354 256 mask or unmask an interrupt, it should call disable_irq() / enable_irq(). 355 257 258 + 4.3.4 pci_msix_vec_count 259 + 260 + int pci_msix_vec_count(struct pci_dev *dev) 261 + 262 + This function could be used to retrieve number of entries in the device 263 + MSI-X table. 264 + 265 + If this function returns a negative number, it indicates the device is 266 + not capable of sending MSI-Xs. 267 + 268 + If this function returns a positive number, it indicates the maximum 269 + number of MSI-X interrupt vectors that could be allocated. 270 + 356 271 4.4 Handling devices implementing both MSI and MSI-X capabilities 357 272 358 273 If a device implements both MSI and MSI-X capabilities, it can 359 274 run in either MSI mode or MSI-X mode, but not both simultaneously. 360 275 This is a requirement of the PCI spec, and it is enforced by the 361 - PCI layer. Calling pci_enable_msi() when MSI-X is already enabled or 362 - pci_enable_msix() when MSI is already enabled results in an error. 363 - If a device driver wishes to switch between MSI and MSI-X at runtime, 364 - it must first quiesce the device, then switch it back to pin-interrupt 365 - mode, before calling pci_enable_msi() or pci_enable_msix() and resuming 366 - operation. This is not expected to be a common operation but may be 367 - useful for debugging or testing during development. 276 + PCI layer. Calling pci_enable_msi_range() when MSI-X is already 277 + enabled or pci_enable_msix_range() when MSI is already enabled 278 + results in an error. If a device driver wishes to switch between MSI 279 + and MSI-X at runtime, it must first quiesce the device, then switch 280 + it back to pin-interrupt mode, before calling pci_enable_msi_range() 281 + or pci_enable_msix_range() and resuming operation. This is not expected 282 + to be a common operation but may be useful for debugging or testing 283 + during development. 368 284 369 285 4.5 Considerations when using MSIs 370 286 ··· 493 381 to bridges between the PCI root and the device, MSIs are disabled. 494 382 495 383 It is also worth checking the device driver to see whether it supports MSIs. 496 - For example, it may contain calls to pci_enable_msi(), pci_enable_msix() or 497 - pci_enable_msi_block(). 384 + For example, it may contain calls to pci_enable_msi_range() or 385 + pci_enable_msix_range().
+35 -21
drivers/ata/ahci.c
··· 1095 1095 {} 1096 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 - unsigned int maxvec; 1101 + int rc, nvec; 1102 1102 1103 - if (!(hpriv->flags & AHCI_HFLAG_NO_MSI)) { 1104 - rc = pci_enable_msi_block_auto(pdev, &maxvec); 1105 - if (rc > 0) { 1106 - if ((rc == maxvec) || (rc == 1)) 1107 - return rc; 1108 - /* 1109 - * Assume that advantage of multipe MSIs is negated, 1110 - * so fallback to single MSI mode to save resources 1111 - */ 1112 - pci_disable_msi(pdev); 1113 - if (!pci_enable_msi(pdev)) 1114 - return 1; 1115 - } 1116 - } 1103 + if (hpriv->flags & AHCI_HFLAG_NO_MSI) 1104 + goto intx; 1117 1105 1106 + rc = pci_msi_vec_count(pdev); 1107 + if (rc < 0) 1108 + goto intx; 1109 + 1110 + /* 1111 + * If number of MSIs is less than number of ports then Sharing Last 1112 + * Message mode could be enforced. In this case assume that advantage 1113 + * of multipe MSIs is negated and use single MSI mode instead. 1114 + */ 1115 + if (rc < n_ports) 1116 + goto single_msi; 1117 + 1118 + nvec = rc; 1119 + rc = pci_enable_msi_block(pdev, nvec); 1120 + if (rc) 1121 + goto intx; 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 1132 pci_intx(pdev, 1); 1119 1133 return 0; 1120 1134 } ··· 1295 1281 1296 1282 hpriv->mmio = pcim_iomap_table(pdev)[ahci_pci_bar]; 1297 1283 1298 - n_msis = ahci_init_interrupts(pdev, hpriv); 1299 - if (n_msis > 1) 1300 - hpriv->flags |= AHCI_HFLAG_MULTI_MSI; 1301 - 1302 1284 /* save initial config */ 1303 1285 ahci_pci_save_initial_config(pdev, hpriv); 1304 1286 ··· 1348 1338 * both CAP.NP and port_map. 1349 1339 */ 1350 1340 n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map)); 1341 + 1342 + n_msis = ahci_init_interrupts(pdev, n_ports, hpriv); 1343 + if (n_msis > 1) 1344 + hpriv->flags |= AHCI_HFLAG_MULTI_MSI; 1351 1345 1352 1346 host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); 1353 1347 if (!host)
+116 -34
drivers/pci/msi.c
··· 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 880 * pci_enable_msi_block - configure device's MSI capability structure 856 881 * @dev: device to configure 857 882 * @nvec: number of interrupts to configure ··· 892 867 int pci_enable_msi_block(struct pci_dev *dev, int nvec) 893 868 { 894 869 int status, maxvec; 895 - u16 msgctl; 896 870 897 - if (!dev->msi_cap || dev->current_state != PCI_D0) 871 + if (dev->current_state != PCI_D0) 898 872 return -EINVAL; 899 873 900 - pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &msgctl); 901 - maxvec = 1 << ((msgctl & PCI_MSI_FLAGS_QMASK) >> 1); 874 + maxvec = pci_msi_vec_count(dev); 875 + if (maxvec < 0) 876 + return maxvec; 902 877 if (nvec > maxvec) 903 878 return maxvec; 904 879 ··· 919 894 return status; 920 895 } 921 896 EXPORT_SYMBOL(pci_enable_msi_block); 922 - 923 - int pci_enable_msi_block_auto(struct pci_dev *dev, int *maxvec) 924 - { 925 - int ret, nvec; 926 - u16 msgctl; 927 - 928 - if (!dev->msi_cap || dev->current_state != PCI_D0) 929 - return -EINVAL; 930 - 931 - pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &msgctl); 932 - ret = 1 << ((msgctl & PCI_MSI_FLAGS_QMASK) >> 1); 933 - 934 - if (maxvec) 935 - *maxvec = ret; 936 - 937 - do { 938 - nvec = ret; 939 - ret = pci_enable_msi_block(dev, nvec); 940 - } while (ret > 0); 941 - 942 - if (ret < 0) 943 - return ret; 944 - return nvec; 945 - } 946 - EXPORT_SYMBOL(pci_enable_msi_block_auto); 947 897 948 898 void pci_msi_shutdown(struct pci_dev *dev) 949 899 { ··· 957 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 961 * @dev: pointer to the pci_dev data structure of MSI-X device function 962 - */ 963 - int pci_msix_table_size(struct pci_dev *dev) 962 + 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 970 u16 control; 966 971 967 972 if (!dev->msix_cap) 968 - return 0; 973 + return -EINVAL; 969 974 970 975 pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control); 971 976 return msix_table_size(control); 972 977 } 978 + EXPORT_SYMBOL(pci_msix_vec_count); 973 979 974 980 /** 975 981 * pci_enable_msix - configure device's MSI-X capability structure ··· 1004 998 if (status) 1005 999 return status; 1006 1000 1007 - nr_entries = pci_msix_table_size(dev); 1001 + nr_entries = pci_msix_vec_count(dev); 1002 + if (nr_entries < 0) 1003 + return nr_entries; 1008 1004 if (nvec > nr_entries) 1009 1005 return nr_entries; 1010 1006 ··· 1111 1103 if (dev->msix_cap) 1112 1104 msix_set_enable(dev, 0); 1113 1105 } 1106 + 1107 + /** 1108 + * pci_enable_msi_range - configure device's MSI capability structure 1109 + * @dev: device to configure 1110 + * @minvec: minimal number of interrupts to configure 1111 + * @maxvec: maximum number of interrupts to configure 1112 + * 1113 + * This function tries to allocate a maximum possible number of interrupts in a 1114 + * range between @minvec and @maxvec. It returns a negative errno if an error 1115 + * occurs. If it succeeds, it returns the actual number of interrupts allocated 1116 + * and updates the @dev's irq member to the lowest new interrupt number; 1117 + * the other interrupt numbers allocated to this device are consecutive. 1118 + **/ 1119 + int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec) 1120 + { 1121 + int nvec = maxvec; 1122 + int rc; 1123 + 1124 + if (maxvec < minvec) 1125 + return -ERANGE; 1126 + 1127 + do { 1128 + rc = pci_enable_msi_block(dev, nvec); 1129 + if (rc < 0) { 1130 + return rc; 1131 + } else if (rc > 0) { 1132 + if (rc < minvec) 1133 + return -ENOSPC; 1134 + nvec = rc; 1135 + } 1136 + } while (rc); 1137 + 1138 + return nvec; 1139 + } 1140 + EXPORT_SYMBOL(pci_enable_msi_range); 1141 + 1142 + /** 1143 + * pci_enable_msix_range - configure device's MSI-X capability structure 1144 + * @dev: pointer to the pci_dev data structure of MSI-X device function 1145 + * @entries: pointer to an array of MSI-X entries 1146 + * @minvec: minimum number of MSI-X irqs requested 1147 + * @maxvec: maximum number of MSI-X irqs requested 1148 + * 1149 + * Setup the MSI-X capability structure of device function with a maximum 1150 + * possible number of interrupts in the range between @minvec and @maxvec 1151 + * upon its software driver call to request for MSI-X mode enabled on its 1152 + * hardware device function. It returns a negative errno if an error occurs. 1153 + * If it succeeds, it returns the actual number of interrupts allocated and 1154 + * indicates the successful configuration of MSI-X capability structure 1155 + * with new allocated MSI-X interrupts. 1156 + **/ 1157 + int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, 1158 + int minvec, int maxvec) 1159 + { 1160 + int nvec = maxvec; 1161 + int rc; 1162 + 1163 + if (maxvec < minvec) 1164 + return -ERANGE; 1165 + 1166 + do { 1167 + rc = pci_enable_msix(dev, entries, nvec); 1168 + if (rc < 0) { 1169 + return rc; 1170 + } else if (rc > 0) { 1171 + if (rc < minvec) 1172 + return -ENOSPC; 1173 + nvec = rc; 1174 + } 1175 + } while (rc); 1176 + 1177 + return nvec; 1178 + } 1179 + EXPORT_SYMBOL(pci_enable_msix_range);
+4 -3
drivers/pci/pcie/portdrv_core.c
··· 79 79 u16 reg16; 80 80 u32 reg32; 81 81 82 - nr_entries = pci_msix_table_size(dev); 83 - if (!nr_entries) 84 - return -EINVAL; 82 + nr_entries = pci_msix_vec_count(dev); 83 + if (nr_entries < 0) 84 + return nr_entries; 85 + BUG_ON(!nr_entries); 85 86 if (nr_entries > PCIE_PORT_MAX_MSIX_ENTRIES) 86 87 nr_entries = PCIE_PORT_MAX_MSIX_ENTRIES; 87 88
+20 -7
include/linux/pci.h
··· 1166 1166 1167 1167 1168 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 1171 return -ENOSYS; 1172 1172 } 1173 1173 1174 - static inline int 1175 - pci_enable_msi_block_auto(struct pci_dev *dev, int *maxvec) 1174 + static inline int pci_enable_msi_block(struct pci_dev *dev, int nvec) 1176 1175 { 1177 1176 return -ENOSYS; 1178 1177 } ··· 1181 1182 static inline void pci_disable_msi(struct pci_dev *dev) 1182 1183 { } 1183 1184 1184 - static inline int pci_msix_table_size(struct pci_dev *dev) 1185 + static inline int pci_msix_vec_count(struct pci_dev *dev) 1185 1186 { 1186 - return 0; 1187 + return -ENOSYS; 1187 1188 } 1188 1189 static inline int pci_enable_msix(struct pci_dev *dev, 1189 1190 struct msix_entry *entries, int nvec) ··· 1205 1206 { 1206 1207 return 0; 1207 1208 } 1209 + 1210 + static inline int pci_enable_msi_range(struct pci_dev *dev, int minvec, 1211 + int maxvec) 1212 + { 1213 + return -ENOSYS; 1214 + } 1215 + static inline int pci_enable_msix_range(struct pci_dev *dev, 1216 + struct msix_entry *entries, int minvec, int maxvec) 1217 + { 1218 + return -ENOSYS; 1219 + } 1208 1220 #else 1221 + int pci_msi_vec_count(struct pci_dev *dev); 1209 1222 int pci_enable_msi_block(struct pci_dev *dev, int nvec); 1210 - int pci_enable_msi_block_auto(struct pci_dev *dev, int *maxvec); 1211 1223 void pci_msi_shutdown(struct pci_dev *dev); 1212 1224 void pci_disable_msi(struct pci_dev *dev); 1213 - int pci_msix_table_size(struct pci_dev *dev); 1225 + int pci_msix_vec_count(struct pci_dev *dev); 1214 1226 int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec); 1215 1227 void pci_msix_shutdown(struct pci_dev *dev); 1216 1228 void pci_disable_msix(struct pci_dev *dev); 1217 1229 void msi_remove_pci_irq_vectors(struct pci_dev *dev); 1218 1230 void pci_restore_msi_state(struct pci_dev *dev); 1219 1231 int pci_msi_enabled(void); 1232 + int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec); 1233 + int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, 1234 + int minvec, int maxvec); 1220 1235 #endif 1221 1236 1222 1237 #ifdef CONFIG_PCIEPORTBUS