Solved bus_alloc_resource fail (return NULL pointer)

I met some problems when requesting MSI-X interrupt resource.
I tried both "amd64 FreeBSD 13.1" and "amd64 FreeBSD 13.2".

Related manual:
https://man.freebsd.org/cgi/man.cgi?query=pci_release_msi&sektion=9&manpath=freebsd-release-ports

1681963075733.png


According to the manual, when requesting MSIX interrupt resource, need to follow the following sequence:

  • bus_alloc_resource(dev, SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE)
  • pci_msix_count
  • pci_alloc_msix
  • bus_setup_intr

But I observed bus_alloc_resource FAIL (return NULL pointer).

Can advice what is the cause of the problem?
Is something wrong with the document or something wrong with the kernel code?
Thanks in advance.
 
Actually, that's not what man page says (copying the text instead of screenshot):
Code:
     The BARs containing the MSI-X vector table and PBA must be allocated via
     bus_alloc_resource(9) before calling pci_alloc_msix() and must not be
     released until after calling pci_release_msi().  Note that the vector
     table and PBA may be stored in the same BAR or in different BARs.

(Trying to recollect and looking at other drivers, which are even better documentation :D)
So you need to bus_alloc_resources_any() with the type of SYS_RES_MEMORY and the rid being that of the PCI BAR containing the vector table (use PCIR_BAR() macro).
Then you count/check the number of vectors using pci_msix_count(), and if it's good, you do pci_alloc_msix(), again checking the count of vectors.
If good, you allocate the resource using bus_alloc_resource_any() with type of SYS_RES_IRQ, flag of RF_ACTIVE, and rid of needed vector (note that numbering starts from 1 for MSI-X).
Finally you set up the interrupt handler using bus_setup_intr() with the rid you got in previous step.
 
Actually, that's not what man page says (copying the text instead of screenshot):
Code:
     The BARs containing the MSI-X vector table and PBA must be allocated via
     bus_alloc_resource(9) before calling pci_alloc_msix() and must not be
     released until after calling pci_release_msi().  Note that the vector
     table and PBA may be stored in the same BAR or in different BARs.

(Trying to recollect and looking at other drivers, which are even better documentation :D)
So you need to bus_alloc_resources_any() with the type of SYS_RES_MEMORY and the rid being that of the PCI BAR containing the vector table (use PCIR_BAR() macro).
Then you count/check the number of vectors using pci_msix_count(), and if it's good, you do pci_alloc_msix(), again checking the count of vectors.
If good, you allocate the resource using bus_alloc_resource_any() with type of SYS_RES_IRQ, flag of RF_ACTIVE, and rid of needed vector (note that numbering starts from 1 for MSI-X).
Finally you set up the interrupt handler using bus_setup_intr() with the rid you got in previous step.
Thanks yuripv79.
You are correct.
I tried the following sequence and it's working:
  • bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE)
  • pci_msix_count
  • pci_alloc_msix
  • bus_alloc_resource(dev, SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE)
  • bus_setup_intr

But I still think the manual is not clear. Is there a way to let community to update the manual so that in future less people will fall into the pitfall?
 
Back
Top