@@ -159,6 +159,11 @@ static int foo_driver_enable_msi(struct pci_dev *pdev, int nvec)
159
159
return pci_enable_msi_range(pdev , nvec , nvec);
160
160
}
161
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
+
162
167
4.2.1.3 Single MSI mode
163
168
164
169
The most notorious example of the request type described above is
@@ -175,7 +180,22 @@ enable the single MSI mode, pci_enable_msi_range() returns either a
175
180
negative errno or 1 (not negative errno or 0 - as pci_enable_msi()
176
181
does).
177
182
178
- 4.2.3 pci_disable_msi
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
179
199
180
200
void pci_disable_msi(struct pci_dev *dev)
181
201
@@ -303,6 +323,11 @@ static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec)
303
323
nvec , nvec);
304
324
}
305
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
+
306
331
4.3.1.3 Specific requirements to the number of MSI-X interrupts
307
332
308
333
As noted above , there could be devices that can not operate with just any
@@ -349,7 +374,64 @@ Note how pci_enable_msix_range() return value is analized for a fallback -
349
374
any error code other than -ENOSPC indicates a fatal error and should not
350
375
be retried.
351
376
352
- 4.3.2 pci_disable_msix
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
353
435
354
436
void pci_disable_msix(struct pci_dev *dev)
355
437
0 commit comments