can not Multiple MSI (WDM)

I am developing a Windows driver for the first time, developing a WDM to study.

For PCI express device developed in xilinx IP, when register an interrupt to the device during IRP_MN_START_DEVICE, and come back in one msi. I use IoConnectInterruptEx.

Do you people understand how anyone?

Test PC

?Windows 7 64bit
?Celeron G1850
?my device PCIe Gen 2.0 (x8 lane) connect to PCIe 3.0 (x8 lane)

Pnp callback

when IRP_MN_FILTER_RESOURCE_REQUIREMENTS,
?receive in the following order:
16 MSIs, 1 MSI, line-based

but IRP_MN_START_DEVICE,
AllocatedResourcesTranslated :
PCM_PARTIAL_RESOURCE_DESCRIPTOR -> Flags is set CM_RESOURCE_INTERRUPT_MESSAGE.

AllocatedResources(Raw) :
u.MessageInterrupt.Raw.MessageCount is 1

my.inf

[xxx_PCIe_Inst.NT.HW]
AddReg=MsiSupportStd

[MsiSupportStd]
HKR,Interrupt Management,0x00000010
HKR,Interrupt Management\MessageSignaledInterruptProperties,0x00000010
HKR,Interrupt Management\MessageSignaledInterruptProperties,MSISupported,0x00010001,1
HKR,Interrupt Management\MessageSignaledInterruptProperties,MessageNumberLimit,0x00010001,16
; checked registers, LC_LOCAL_MACHINE/SYSTEM/…/PCI/‘MyDevice’/

IoConnectInterruptEx code

IO_CONNECT_INTERRUPT_PARAMETERS params;
params.Version = CONNECT_MESSAGE_BASED;
params.MessageBased.PhysicalDeviceObject = MyPhysicalObject;
params.MessageBased.MessageServiceRoutine = TestInterruptMessageService;
params.MessageBased.ServiceContext = (PVOID)MyFdo;
params.MessageBased.SpinLock = &MySpinLock;
params.MessageBased.SynchronizeIrql = 0;
params.MessageBased.FloatingSave = FALSE;
params.MessageBased.FallBackServiceRoutine = TestMsiFallbackInterruptService;
params.MessageBased.ConnectionContext.Generic = &MyConnectionContext.Generic;

status = IoConnectInterruptEx(&params);
// status is SUCCESS
// params.Version is CONNECT_MESSAGE_BASED
// (*(params.MessageBased.ConnectionContext.InterruptMessageTable))->MessageCount is 1

PCI configuration space

PCIe MSI capability :
Control :
?? MSI Enable : It becomes 1 when call the IoConnectInterruptEx from 0
Multiple Message Capable : 4 (= 16 MSIs)
Multiple Message Enable : 0
Address64bit : 1
PerVectorMaskCapable : 0 ( xilinx IP not supported? )

PCIe capability :
Capabilities :

Interrupt Message Number : 1
If the test was set to 4 “PCIe MSI capability.Multiple Message Enable”, InterruptMessageNumber is 16.

xxxxx@microbrain.ne.jp wrote:

I am developing a Windows driver for the first time, developing a WDM to study.

For PCI express device developed in xilinx IP, when register an interrupt to the device during IRP_MN_START_DEVICE, and come back in one msi. I use IoConnectInterruptEx.

Do you people understand how anyone?

Pnp callback

when IRP_MN_FILTER_RESOURCE_REQUIREMENTS,
?receive in the following order:
16 MSIs, 1 MSI, line-based

but IRP_MN_START_DEVICE,
AllocatedResourcesTranslated :
PCM_PARTIAL_RESOURCE_DESCRIPTOR -> Flags is set CM_RESOURCE_INTERRUPT_MESSAGE.

AllocatedResources(Raw) :
u.MessageInterrupt.Raw.MessageCount is 1

There are a limited number of interrupt slots available. If you ask for
multiple messages, but the PnP manager cannot allocate the number of MSI
message interrupts that you want, it will allocate exactly one.

http://msdn.microsoft.com/en-us/library/windows/hardware/ff548079.aspx


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Are you trying to use MSI or MSI-X?

>params.MessageBased.SynchronizeIrql = 0;

Hmmm, isn’t the IRQL passed to your driver by the PNP Manager via a CM_PARTIAL_RESOURCE_DESCRIPTOR. structure ?

And I think IRQL zero is called PASSIVE_LEVEL, but PASSIVE_LEVEL interrupts are supported starting with Windows 8.

I may be wrong but I think you are on the wrong path. Just surrender.

Thank you for your reply.

Alex Grig wrote:

Are you trying to use MSI or MSI-X?
I want to use the MSI.

Enola Gay wrote:

And I think IRQL zero is called PASSIVE_LEVEL, but PASSIVE_LEVEL interrupts are supported
starting with Windows 8.
I was not aware of that limit.

Tim Roberts wrote:

If you ask for multiple messages, but the PnP manager cannot allocate the number of MSI
message interrupts that you want, it will allocate exactly one.
Hmm … I’ll try to reduce the number of MSI.

I’ll try the day after tomorrow.

Why do you need multiple MSI interrupts?

MSI interrupts are deprecated because each device even requesting one interrupt may take a block of 16 vectors.

Get with the program and use MSI-X.

Is it a kind of a grim humor to respond to the question by a Japanese person using the nickname of “Enola Gay”?


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

wrote in message news:xxxxx@ntdev…
> >params.MessageBased.SynchronizeIrql = 0;
>
> Hmmm, isn’t the IRQL passed to your driver by the PNP Manager via a CM_PARTIAL_RESOURCE_DESCRIPTOR. structure ?
>
> And I think IRQL zero is called PASSIVE_LEVEL, but PASSIVE_LEVEL interrupts are supported starting with Windows 8.
>
> I may be wrong but I think you are on the wrong path. Just surrender.
>
>

> And I think IRQL zero is called PASSIVE_LEVEL, but PASSIVE_LEVEL interrupts are supported > starting with Windows 8.
It was set to APC_LEVEL but, MSI was one.

Why do you need multiple MSI interrupts?
MSI interrupts are deprecated because each device even requesting one interrupt may take a
block of 16 vectors.
Get with the program and use MSI-X.
I’d better of using the MSI-X.

Let’s be clear: MSI is DEFinitely not deprecated. “Discouraged” perhaps. But in no way deprecated. Yes, MSIs must be allocated on “natural” boundaries, and this will limit the availability of multiple vectors.

There’s a lot of issues in this thread.

First, the previous responders are correct: reduce the number of MSIs you ask for, or go with MSI-x. If you want MSI, try 4 vectors.

Second, why do you want your ISR to run below the device IRQL? All thus will do is very substantially increase your overhead and latency. PASSIVE_LEVEL interrupts are designed for devices that need to do additional processing in their ISRs that can’t be done at DIRQL… like sending a request to another driver to determine if the device is interrupting.

Perhaps you can explain what you’re goal is, and then we can advise you on how you might best achieve that goal.

Peter
OSR
@OSRDrivers

> First, the previous responders are correct
The number of MSI I need is 2. However, since troubled You can not be the case where it is needed, I had to specify the maximum number of MSI.

Second, why do you want your ISR to run below the device IRQL?
sorry. I was attempting only registered the interrupt as a first step.
So do not be too much yet understand. This has been in care, but it is a situation that you have tried to comply with the sample on MSDN.
http://msdn.microsoft.com/en-us/library/windows/hardware/ff565530(v=vs.85).aspx

Perhaps you can explain what you’re goal is, and then we can advise you on how you might best achieve that goal.
The reason I need multiple whether, Interrupts is
1 : DMA transfer start and end request.
2 : other factors.
And, are prohibited access to BAR during DMA transfer.
Then, it is required interruption of other factors might be notified DMA transfer.
I have needs to wait for access BAR by recognizing the type of interrupt.

I am currently exploring this thing.
If you have received this problem, how do you cope?

On Sep 1, 2014, at 6:47 PM, xxxxx@microbrain.ne.jp wrote:

The reason I need multiple whether, Interrupts is
1 : DMA transfer start and end request.
2 : other factors.
And, are prohibited access to BAR during DMA transfer.

I have to believe that you are misunderstanding something, because no hardware designer would ever make a design like this. You HAVE to be able to access the BARs during DMA transfer. Otherwise, how are you going to be able to acknowledge the interrupt to stop it from firing?

If you have received this problem, how do you cope?

The correct solution is to have at ?interrupts pending" register in your BAR, with one bit for each possible interrupt source. Your ISR checks to see which bit(s) are set, handles them, and clears them.
?
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

quote>

The correct solution is to have at ?interrupts pending" register in your BAR,
with one bit for each possible interrupt source. Your ISR checks to see which
bit(s) are set, handles them, and clears them.
[/quote]

Or do the equivalent using in-memory data structures… Thus avoiding the slow down required by accessing your device registers from you ISR. This is the preferred method when using MSI for DMA devices.

Peter
OSR
@OSRDrivers

> how are you going to be able to acknowledge the interrupt to stop it from firing?
Originally, I was thinking that interrupt is used as lock to read BARs,
and it was going to ask them to allow only write.

The correct solution is to have at “interrupts pending” register in your BAR, with one bit for each possible interrupt source.
Your ISR checks to see which bit(s) are set, handles them, and clears them.
Or do the equivalent using in-memory data structures… Thus avoiding the slow down required by accessing your device registers from you ISR.
This is the preferred method when using MSI for DMA devices.
i will try to assemble once more in that direction.

Peter Viscarola wrote:

If you want MSI, try 4 vectors.
successful that it is 4 vectors.

and arrived here while look for “natural boundary” and “MSI-X”.
http://www.osronline.com/showthread.cfm?link=237582

you were recommended to me for this reason.

I became very study. Thank you for your help.

xxxxx@osr.com wrote:

Or do the equivalent using in-memory data structures… Thus avoiding the slow down required by accessing your device registers from you ISR. This is the preferred method when using MSI for DMA devices.

I’m not sure I see what you are saying. With an in-memory data
structure, how would the hardware set the bits to let me know which
interrupt source fired? Another DMA?

Maybe I just haven’t encountered a device that uses this paradigm yet.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

While you *definitely* must have a way to determine if your device is interrupting, that way does *not* need to be in a register. The ideal handing of an MSI/MSI-X would be to not have to touch a register at all, right?

You might have a continuous-mode DMA device (using shared memory) that updates in-memory bitfields with status… or, more commonly, the device simply updates a completion list in memory that you can check. Consider something like, oh, NVMe where you create a submission queue entry in shared memory to request a read/write on the disk (including a descriptor of the user data buffer) – When the read/write is done, the NVMe device makes an entry in an appropriate completion queue (again, in shared memory) and generates an MSI/MSI-X. Your driver checks the completion queue to determine if there’s work to do. No register access required (in this simple scenario).

Peter
OSR
@OSRDrivers