简体   繁体   中英

Custom linux pcie driver MSI interrupts

I am writing a custom linux PCIe driver for an embedded device. For this purpose I need to enable multiple MSI vectors. When I use the function pci_enable_msi(pdev) the code works properly. However when I use pci_enable_msi_block(pdev,4); the function returns 1 meaning it can only allocate 1 interrupt. If I use pci_enable_msi_block(pdev,32); the function returns 16 upon which I use pci_enable_msi_block(pdev,16); but the return value is again 1.

I tried to check the return value for all possible arguments and the result was as below:

for(i=2;i<33;i++)
    {
       ret = pci_enable_msi_block(pdev,i);
       printk(KERN_DEBUG "For request i=%d the return value is=%d\n",i, ret);
    }


[   89.421184] For request i=2 the return value is=1
[   89.421196] For request i=3 the return value is=1
[   89.421208] For request i=4 the return value is=1
[   89.421220] For request i=5 the return value is=1
[   89.421232] For request i=6 the return value is=1
[   89.421243] For request i=7 the return value is=1
[   89.421255] For request i=8 the return value is=1
[   89.421266] For request i=9 the return value is=1
[   89.421278] For request i=10 the return value is=1
[   89.421290] For request i=11 the return value is=1
[   89.421301] For request i=12 the return value is=1
[   89.421313] For request i=13 the return value is=1
[   89.421325] For request i=14 the return value is=1
[   89.421336] For request i=15 the return value is=1
[   89.421348] For request i=16 the return value is=1
[   89.421353] For request i=17 the return value is=16
[   89.421359] For request i=18 the return value is=16
[   89.421364] For request i=19 the return value is=16
[   89.421369] For request i=20 the return value is=16
[   89.421374] For request i=21 the return value is=16
[   89.421380] For request i=22 the return value is=16
[   89.421385] For request i=23 the return value is=16
[   89.421390] For request i=24 the return value is=16
[   89.421395] For request i=25 the return value is=16
[   89.421401] For request i=26 the return value is=16
[   89.421406] For request i=27 the return value is=16
[   89.421411] For request i=28 the return value is=16
[   89.421416] For request i=29 the return value is=16
[   89.421422] For request i=30 the return value is=16
[   89.421427] For request i=31 the return value is=16
[   89.421432] For request i=32 the return value is=16

the function call is successful (returns 0) only when pci_enable_msi_block(pdev,1) is used.

I have also tried to use the pci_enable_msi_exact and pci_enable_msi_range functions but then the code does not compile and gives an implicit function declaration error.

Kindly provide suggestions on how to resolve this issue so that I can use four MSI vectors.

You will need to check your configuration registers to determine how many MSI are available to be allocated. The PCIe device determines this.

You will need to probe configuration registers. Take the LSB of the DWORD to obtain the command register. This controls legacy interrupts. Take the MSB of address 0x50 to determine the message control. This controls the MSI.

Make sure that legacy interrupts are disabled and bus master enabled in the command register. Use 0x50 (MSB) to determine how many MSI can be allocated. bits 4:6 determine this and bit 0 enables MSI.

I ran into a similar problem but it turned out that my endpoint was only capable of a single MSI and I was unable to change that due to vendor limitations.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM