Message Signaled Interrupt problem

I am having trouble with an MSI device.

I am calling IoConnectToInterruptEx(…) with the message based fields of
the parameter structure filled in. The result is always a fall back to a
line based interrupt.

I can see that the adapter has MSI capability (see below).

My client told me that the test computer has MSI capability (how can I
confirm this?).

I plan to use the iointex library to allow a single source for XP through
Windows 7 but have tested without the library on Windows 7 with the same
results.

My code is based on the WDK example of using the iointex libray (
http://msdn.microsoft.com/en-us/library/ff565402(v=vs.85).aspx ) modified
with the necessary corrections (set the pointer for the return structure and
check the return for the type of interrupt returned).

Is there any way to determine why the connect fell back to a line based
interrupt?

Did I miss something else in my code (see below)?

Ed

========================================================================

PCI Configuration Space (Segment:0000 Bus:06 Device:00 Function:00)

Common Header:

00: VendorID 16d5

02: DeviceID 5808

04: Command 0107 IOSpaceEn MemSpaceEn BusInitiate SERREn

06: Status 4010 CapList SERR

08: RevisionID 00

09: ProgIF 00

0a: SubClass 80 Other Signal Processing Controller

0b: BaseClass 11 Signal Processing

0c: CacheLineSize 0010 BurstDisabled

0d: LatencyTimer 00

0e: HeaderType 00

0f: BIST 00

10: BAR0 febff004

14: BAR1 00000000

18: BAR2 fe400004

1c: BAR3 00000000

20: BAR4 fd800004

24: BAR5 00000000

28: CBCISPtr 00000000

2c: SubSysVenID 16d5

2e: SubSysID 5808

30: ROMBAR fea00000

34: CapPtr 40

3c: IntLine 0a

3d: IntPin 01

3e: MinGnt 00

3f: MaxLat 00

Device Private:

40: 00034801 00000000 00806005 00000000

50: 00000000 00000000 00000000 00000000

60: 00010010 012c8fe9 00022800 0003f441

70: 10410040 00000000 00000000 00000000

80: 00000000 00000000 00000000 00000000

90: 00000000 00000000 00000000 00000000

a0: 00000000 00000000 00000000 00000000

b0: 00000000 00000000 00000000 00000000

c0: 00000000 00000000 00000000 00000000

d0: 00000000 00000000 00000000 00000000

e0: 00000000 00000000 00000000 00000000

f0: 00000000 00000000 00000000 00000000

Capabilities:

40: CapID 01 PwrMgmt Capability

41: NextPtr 48

42: PwrMgmtCap 0003 Version=3

44: PwrMgmtCtrl 0000 DataScale:0 DataSel:0 D0

48: CapID 05 MSI Capability

49: NextPtr 60

4a: MsgCtrl 64BitCapable MultipleMsgEnable:0 (0x1)
MultipleMsgCapable:0 (0x1)

4c: MsgAddr 0

50: MsgAddrHi 0

54: MsData 0

60: CapID 10 PCI Express Capability

61: NextPtr 00

62: Express Caps 0001 Type:Endpoint

64: Device Caps 012c8fe9

68: Device Control 2800 MRR:512 NS ap pf et MP:128 ro ur fe nf ce

6a: Device Status 0002 tp ap ur fe NF ce

6c: Link Caps 0003f441

70: Link Control 0040 es CC rl ld RCB:64 ASPM:None

72: Link Status 1041 SCC lt lte NLW:x4 LS:2.5

74: Slot Caps 00000000

78: Slot Control 0000 pcc PI:?? AI:?? hpi cc pde mrls pfd ab

7a: Slot Status 0000 pds hpi cc pdc ms pfd ab

7c: Root Control 0000 pmei fs nfs cs

7e: Reserved 0000

80: Root Status 00000000 pmep pmes ID:0

Enhanced Capabilities:

100: CapID 0003 Serial Number Capability

Version 1

NextPtr 000

===========================================================================

{

IO_CONNECT_INTERRUPT_PARAMETERS params;

DevExt->MessageInterruptUsed = FALSE;

RtlZeroMemory( &params,
sizeof(IO_CONNECT_INTERRUPT_PARAMETERS) );

params.Version = CONNECT_MESSAGE_BASED;

// Set members of params.MessageBased here.

params.MessageBased.PhysicalDeviceObject =
DevExt->UnderlyingPDO;

params.MessageBased.MessageServiceRoutine =
InterruptMessageServiceRoutine;

params.MessageBased.ServiceContext = DevExt ;

params.MessageBased.SpinLock = NULL;

params.MessageBased.SynchronizeIrql = 0;

params.MessageBased.FloatingSave = FALSE;

params.MessageBased.FallBackServiceRoutine =
HandleInterrupt;

params.MessageBased.ConnectionContext.Generic =
(PVOID)&DevExt->ConnectionContext;

DebugPrint(LOUD, DBG_INIT, “calling IoConnectInterruptEx -
MessageBased\n” );

status = IoConnectInterruptEx(&params);

if ( NT_SUCCESS(status) )

{

// Operation succeeded. We are running on Windows
Vista.

SET_FLAG(DevExt->Flags, ADAPTER_INTERRUPT_IN_USE);

DebugPrint(LOUD, DBG_INIT, “IoConnectInterruptEx
succeeded. We are running on Windows Vista or later.\n” );

//

// Save the type of interrupt connected. We’ll use
this and also the returned connection

// context later when we need to disconnect from the
interrupt.

//

DevExt->IntConnectVersion = params.Version;

// Check to see… Did we connect to any Message
Signaled Interrupts, or did we

// have to fall back to using traditional line-based
interrupts? IoConnectInterruptEx

// sets the Version field to indicate the interrupt
type to which we actually were connected.

//

if(params.Version == CONNECT_MESSAGE_BASED)

{

// PIO_INTERRUPT_MESSAGE_INFO msgInfo;

DebugPrint(LOUD, DBG_INIT, " Message
Signaled Interrupt connected.\n" );

//

// Because we succeeded in connceting to one
or more Message Signaled Interrupts, the

// connection context that was returned was a
pointer to an IO_INTERRUPT_MESSAGE_INFO structure.

//

// msgInfo =
DevExt->ConnectionContext.InterruptMessageTable;

// devExt->MessageUsed = TRUE;

DevExt->MessageInterruptUsed = TRUE; // We’re
using message-based interrupts.

//

// Get count of Message Signaled Interrupts we
were granted Note: Even though our device

// requests more, we could be granted only 1
Message Signaled Interrupt in certain situations.

// Deal with that here…

//

DevExt->IntMessageCount =
(*DevExt->ConnectionContext.InterruptMessageTable)->MessageCount;

}

else

{

ASSERT(Version == CONNECT_LINE_BASED);

DebugPrint(LOUD, DBG_INIT, " Line Interrupt
connected.\n" );

DevExt->MessageInterruptUsed = FALSE; // We’re
not using message-based interrupts.

}

}

else

{

// Running an older Windows - call
IoconnectInterruptEx with CONNECT_FULLY_SPECIFIED

}

}

You also need some .inf file changes to enable MSI-X … what do those look like?

The INF file has the enable for MSI interrupts:

HKR,Interrupt Management,0x00000010
HKR,Interrupt Management\MessageSignaledInterruptProperties,0x00000010
HKR,Interrupt
Management\MessageSignaledInterruptProperties,MSISupported,0x00010001,1

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of choward@ix.netcom.com
Sent: Wednesday, April 06, 2011 12:56 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Message Signaled Interrupt problem

You also need some .inf file changes to enable MSI-X … what do those look
like?


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

IIRC, XP always changes MSI to line interrupts.

Larry C

Ed and I communicate a lot, so I have gone through this with him, he at
present is running Win7. He is looking for a binary that can run from XP
to Win7.

Don Burn (MVP, Windows DKD)
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

xxxxx@honeywell.com” wrote in
message news:xxxxx@ntdev:

> IIRC, XP always changes MSI to line interrupts.
>
> Larry C

I have a WDF driver for our PCIe card that works from XP thru Win7, but I our install package picks up a different binary depending on the platform. It is however the same code, just built in the different environment.

Larry C

Maybe the question should be “Does the iointex library for things to
line interrupts?”

Don Burn (MVP, Windows DKD)
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

xxxxx@honeywell.com” wrote in
message news:xxxxx@ntdev:

> I have a WDF driver for our PCIe card that works from XP thru Win7, but I our install package picks up a different binary depending on the platform. It is however the same code, just built in the different environment.
>
> Larry C

Based on a casual check, it looks like the library should “do the right thing” and call the REAL routine if it’s available (on Vista and later).

You should be able to verify this by walking into the function, and quickly see if the redirecting stub function is eventually calling the real IoConnectInterruptEx or not.

Peter
OSR

In my message I intended to state that for testing I removed references the
iointex library and am testing on Windows 7.

I removed the iointex library references to test if my problem was with the
library. Since the problem exists without the library I was able to
demonstrate that the library is not the source of my bug.

Sorry my description was not clear.

Ed

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@osr.com
Sent: Wednesday, April 06, 2011 3:32 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Message Signaled Interrupt problem

Based on a casual check, it looks like the library should “do the right
thing” and call the REAL routine if it’s available (on Vista and later).

You should be able to verify this by walking into the function, and quickly
see if the redirecting stub function is eventually calling the real
IoConnectInterruptEx or not.

Peter
OSR


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer