Forum Discussion
Altera_Forum
Honored Contributor
15 years agoHow to request multiply MSI interrupts?
Hi !!!
Developing a network device driver on Arria2 GX (Avalon-ST). Is it possible to set a vector of 8 MSI interrupts , if the design supports only MSI interrupts, not MSI - X? From the side of device driver developer - to request 8 separate interrupt handlers, to handle 8 packet queues. pci_enable_msi_block() returns 1.This means, that it's possible to request only 1 interrupt line. The capabilities of device: Capabilities: [78] Power Management version 3 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Capabilities: [80] Express (v1) Endpoint, MSI 00 DevCap: MaxPayload 256 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset- DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported- RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+ MaxPayload 128 bytes, MaxReadReq 512 bytes DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend- LnkCap: Port# 1, Speed 2.5GT/s, Width x4, ASPM L0s, Latency L0 unlimited, L1 unlimited ClockPM- Suprise- LLActRep- BwNot- LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk+ ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt- LnkSta: Speed 2.5GT/s, Width x4, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt- Developing under Linux. Best Regards, Igor39 Replies
- Altera_Forum
Honored Contributor
Hi,
Once more thanks a lot for your advice about Linux Driver Programming. Rigth now how to deal with Interrupt Service Routine because I have 8 MSI Source. Should I write 8 ISR? Here is a piece of my code --- Quote Start --- ------------------------------------------------------------------------------------------ /* Interrupt Handler */ void LATTICE_pci_intr_handler (int irq, void *dev_id, struct pt_regs *regs) { unsigned long intr_flag; /* Lese Interrupt-Flag, um zu pruefen, ob das LATTICE PCI-Board ueberhaupt */ /* Quelle des Interrupts ist. (Moeglicherweise Shared Interrupt!) */ intr_flag = readl (LATTICE_pci_dev.virt_addr + LATTICE_INTR_REG_ADDR) & 1; if (intr_flag) return; /* Kein Interrupt durch das LATTICE PCI-Board */ /* Hier beginnt die eigentliche Interrupt-Bearbeitung... */ printk ("LATTICE PCI-Board: Interrupt!\n"); } ........ /* Interrupt-Handler registrieren */ if (request_irq (LATTICE_pci_dev.intr_line, LATTICE_pci_intr_handler, SA_SHIRQ, LATTICE_PCI_NAME, &LATTICE_pci_dev)) { printk ("LATTICE PCI-Board: can't get assigned IRQ %d.\n", LATTICE_pci_dev.intr_line); result = -EIO; goto exit1; } --- Quote End --- - Altera_Forum
Honored Contributor
Hi
In your case , the LATTICE_pci_intr_handler function will handle the MSI irq. int irq - the number of MSI irq, which you received. If you want to use 8 MSI, this code is probably correct. if 8 MSI-X, you need to request_irq on every interrupt line. Regards, Igor - Altera_Forum
Honored Contributor
Ok!
it means my LATTICE_pci_intr_handler function handle all the MSI(0-7) GENERATED IRQ. But let assume I want to test my CAN and UART by a simple function to make sure the appropriate function will be called depending on which device assert the Interrupt. void testCAN() { printf ("Called by CAN BUS!\n"); } and void testUART() { printf ("Called by UART!\n"); } How can I implemented these 2 functions within the Interrupt Handler or should I simply test the IRQ Number and called the related function ?? 0--CAN 1--UART ...
- Altera_Forum
Honored Contributor
Yes.
If you have a single MSI vector, you have to register 1 interrupt line. If you want to test CAN, UART interrupts, than write your kernel module. Request irq for CAN, than for UART, with interrupt handlers. For ex: static irqreturn_t can_isr ( int irq, void *dev ) { void testCAN(); printk(KERN_DEBUG " CAN received irq = %d \n", irq); return IRQ_HANDLED; } static irqreturn_t uart_isr ( int irq, void *dev ) { void testUART(); printk(KERN_DEBUG " UART received irq = %d \n", irq); return IRQ_HANDLED; } - Altera_Forum
Honored Contributor
Hi,
I can understand the code on Linux, where it has to acquire the IRQ for the MSI and it needs the ISR handler to perform interrupt function when it receive particular interrupt signal from the IRQ allocated. However, I need some guidelines on 1) how to generate MSI interrupt in Altera? Please anyone if have any recommended examples. 2) and what values should be configured to these signals? app_msi_tc[2:0] in Application MSI traffic class: This signal indicates the Traffic Class (TC) used to send the MSI (unlike INTx interrupts, any TC can be used to send MSIs). app_msi_num[4:0] in Application MSI Offset Number: This signal is used by the Application to determine the offset between the base message data and the MSI to send. 3) how to make sure that the MSI that I generate is after DMA write from FPGA to PC completed? so that it wont corrupt my DMA write data. Advice needed and thank you. - Altera_Forum
Honored Contributor
Ok for the advice!
Now I finally implemented my first MSI Interrupt. But 1 ) why I can not get pci-msi-edge on my device after the linux command:cat /proc/interrupts while it looks good with the command lspci -d 1204:ec30 -v -xxx ( see the 2 outputs below) 2) I permanently get an error by implementing pci_enable_msi_block (struct pci_dev * dev, unsigned int nvec) where can I get the related patch for arch x86?
--- Quote Start --- Yes. If you have a single MSI vector, you have to register 1 interrupt line. If you want to test CAN, UART interrupts, than write your kernel module. Request irq for CAN, than for UART, with interrupt handlers. For ex: static irqreturn_t can_isr ( int irq, void *dev ) { void testCAN(); printk(KERN_DEBUG " CAN received irq = %d \n", irq); return IRQ_HANDLED; } static irqreturn_t uart_isr ( int irq, void *dev ) { void testUART(); printk(KERN_DEBUG " UART received irq = %d \n", irq); return IRQ_HANDLED; } --- Quote End ---# lspci -d 1204:ec30 -v -xxx 04:00.0 Non-VGA unclassified device: Lattice Semiconductor Corporation Device ec30 Subsystem: Lattice Semiconductor Corporation Device 3030 Physical Slot: 3 Flags: bus master, fast devsel, latency 0, IRQ 30 Memory at d0440000 (32-bit, non-prefetchable) Memory at d0400000 (32-bit, non-prefetchable) Capabilities: Power Management version 3 Capabilities: MSI: Enable+ Count=1/1 Maskable- 64bit+ Capabilities: Express Endpoint, MSI 00 Capabilities: Device Serial Number 00-00-00-00-00-00-00-00 00: 04 12 30 ec 07 04 10 00 00 00 00 00 10 00 00 00 10: 00 00 44 d0 00 00 40 d0 00 00 00 00 00 00 00 00 20: 00 00 00 00 00 00 00 00 00 00 00 00 04 12 30 30 30: 00 00 00 00 50 00 00 00 00 00 00 00 07 01 00 00 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 50: 01 70 03 00 00 00 00 00 00 00 00 00 00 00 00 00 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 70: 05 90 81 00 0c 10 e0 fe 00 00 00 00 a9 41 00 00 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90: 10 00 01 00 00 80 00 00 00 00 00 00 11 74 00 00 a0: 00 00 11 00 00 00 00 00 00 00 00 00 00 00 00 00 b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # cat /proc/interrupts CPU0 0: 116261 IO-APIC-edge timer 1: 2 IO-APIC-edge i8042 3: 2 IO-APIC-edge 4: 2 IO-APIC-edge 5: 0 IO-APIC-edge parport0 7: 0 IO-APIC-edge LATTICE_pci 8: 1 IO-APIC-edge rtc0 9: 0 IO-APIC-fasteoi acpi 12: 4 IO-APIC-edge i8042 16: 79998 IO-APIC-fasteoi pciehp, pciehp, pciehp, pciehp, ehci_hcd:usb2, ohci_hcd:usb6, ohci_hcd:usb7, ohci_hcd:usb8, HDA Intel 18: 0 IO-APIC-fasteoi mmc0, mmc1 19: 13861 IO-APIC-fasteoi ehci_hcd:usb1, ohci_hcd:usb3, ohci_hcd:usb4, ohci_hcd:usb5 24: 0 PCI-MSI-edge aerdrv 25: 2 PCI-MSI-edge aerdrv, pciehp - Altera_Forum
Honored Contributor
What does pci_enable_msi_block return ?
- Altera_Forum
Honored Contributor
--- Quote Start --- 7: 0 IO-APIC-edge LATTICE_pci --- Quote End --- You enabled Legacy interrupts. Not MSI - Altera_Forum
Honored Contributor
It seems to be disable by executing the command cat /proc/interrupts
But in the other hand my msi is enabled by the following command lspci -d 1204:ec30 -v -xxx (see output below) ?
# lspci -d 1204:ec30 -v -xxx 04:00.0 Non-VGA unclassified device: Lattice Semiconductor Corporation Device ec30 Subsystem: Lattice Semiconductor Corporation Device 3030 Physical Slot: 3 Flags: bus master, fast devsel, latency 0, IRQ 30 Memory at d0440000 (32-bit, non-prefetchable) Memory at d0400000 (32-bit, non-prefetchable) Capabilities: Power Management version 3 Capabilities: MSI: Enable+ Count=1/1 Maskable- 64bit+ Capabilities: Express Endpoint, MSI 00 Capabilities: Device Serial Number 00-00-00-00-00-00-00-00 00: 04 12 30 ec 07 04 10 00 00 00 00 00 10 00 00 00 10: 00 00 44 d0 00 00 40 d0 00 00 00 00 00 00 00 00 20: 00 00 00 00 00 00 00 00 00 00 00 00 04 12 30 30 30: 00 00 00 00 50 00 00 00 00 00 00 00 07 01 00 00 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 50: 01 70 03 00 00 00 00 00 00 00 00 00 00 00 00 00 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 70: 05 90 81 00 0c 10 e0 fe 00 00 00 00 a9 41 00 00 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90: 10 00 01 00 00 80 00 00 00 00 00 00 11 74 00 00 a0: 00 00 11 00 00 00 00 00 00 00 00 00 00 00 00 00 b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - Altera_Forum
Honored Contributor
Advice: Output based on one msi
# lspci -d 1204:ec30 -v -xxx 04:00.0 Non-VGA unclassified device: Lattice Semiconductor Corporation Device ec30 Subsystem: Lattice Semiconductor Corporation Device 3030 Physical Slot: 3 Flags: bus master, fast devsel, latency 0, IRQ 30 Memory at d0440000 (32-bit, non-prefetchable) Memory at d0400000 (32-bit, non-prefetchable) Capabilities: Power Management version 3 Capabilities: MSI: Enable+ Count=1/1 Maskable- 64bit+ Capabilities: Express Endpoint, MSI 00 Capabilities: Device Serial Number 00-00-00-00-00-00-00-00 00: 04 12 30 ec 07 04 10 00 00 00 00 00 10 00 00 00 10: 00 00 44 d0 00 00 40 d0 00 00 00 00 00 00 00 00 20: 00 00 00 00 00 00 00 00 00 00 00 00 04 12 30 30 30: 00 00 00 00 50 00 00 00 00 00 00 00 07 01 00 00 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 50: 01 70 03 00 00 00 00 00 00 00 00 00 00 00 00 00 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 70: 05 90 81 00 0c 10 e0 fe 00 00 00 00 a9 41 00 00 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90: 10 00 01 00 00 80 00 00 00 00 00 00 11 74 00 00 a0: 00 00 11 00 00 00 00 00 00 00 00 00 00 00 00 00 b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00