windows - MSI-X interrupts in WDF -


i'm having lot of trouble getting msi-x interrupts implemented in windows bus driver we're writing in wdf / kmdf. i've read msdn documentation, , there's not lot of helpful info there. understanding should "work".

i've changed our driver's inf file add appropriate registry keys , confirmed being set working on install. i'm querying pci config space , determining whether msi-x interrupts supported.

the problem once have information, don't know how change code set interrupt msi-x. standard calls configure wdf_interrupt_config_init stuct , call wdfinterruptcreate, interrupt created not message-signaled, , don't know needs done make happen.

is there wdf version of steps here, or should doing standard wdfinterrupt creation steps here?

does have experience doing this? can provide source example?

i have been struggling similar in last week. application different because trying plain msi interrupts rather msi-x interrupts work. using wdf framework in pretty same way.

i realize posted original question around april of 2013, there no updates. have solved original problem? if so, see own solution.

in wdf driver, mapping incoming hardware resource list , parsing using wdfcmresourcelistgetdescriptor() function examine each pcm_partial_resource_descriptor item in wdfcmreslist list. able obtain single cmresourcetypeinterrupt descriptor, legacy interrupt instead of msi interrupt. device support msi. did not understand why msi descriptor not in resource list, after setting registry entries in .inf file described.

it turns out had typo in .inf file. had forgotten append ".hw" suffix in device install section. adding suffix allows bus manager modify pcie config addresses in device , create appropriate msi interrupt resource descriptor, must hooked driver.

[standard.nt$arch$] %tdvr.devicedesc%=tdvr_device, pci\ven_104c&dev_b800   [tdvr_device.nt] copyfiles=drivers_dir  [tdvr_device.nt.hw] addreg=msi_interrupts  [drivers_dir] tdvr.sys  ;http://msdn.microsoft.com/en-us/library/windows/hardware/ff544246(v=vs.85).aspx ;to receive message-signaled interrupts (msis), driver's inf file must enable msis in  ;registry during installation. use interrupt management\messagesignaledinterruptproperties  ;subkey of device's hardware key enable msi support.  [msi_interrupts] hkr,interrupt management,,0x00000010 hkr,interrupt management\messagesignaledinterruptproperties,,0x00000010 hkr,interrupt management\messagesignaledinterruptproperties,msisupported,0x00010001,1 

when msi interrupt resource descriptor found in resource list (for example in evtmaphwresources callback), descriptor used input wdfinterruptcreate() function. "tdvr" prefixes here own driver naming convention.

ntstatus tdvrconfigureinterrupts(     _inout_ pdevice_context devicecontext,     _in_ pcm_partial_resource_descriptor interruptdescraw,     _in_ pcm_partial_resource_descriptor interruptdesctranslated     ) {     ntstatus status;     paged_code();     funcentry();      // kind of interrupt has been provided?     if (cm_resource_interrupt_message & interruptdesctranslated->flags)     {         traceinterrupt(trace_level_information,              "message interrupt level 0x%0x, vector 0x%0x, messagecount %u\n"             ,interruptdesctranslated->u.messageinterrupt.translated.level             ,interruptdesctranslated->u.messageinterrupt.translated.vector             ,interruptdesctranslated->u.messageinterrupt.raw.messagecount             );     }     else     {         traceinterrupt(trace_level_information,             "legacy interrupt level: 0x%0x, vector: 0x%0x\n"             ,interruptdesctranslated->u.interrupt.level             ,interruptdesctranslated->u.interrupt.vector             );     }      //     // create wdfinterrupt object.     //     wdf_interrupt_config interruptconfig;     wdf_interrupt_config_init(         &interruptconfig,         tdvrevtinterruptisr,         tdvrevtinterruptdpc         );      // each interrupt has context data     wdf_object_attributes interruptattributes;     wdf_object_attributes_init_context_type(         &interruptattributes,         interrupt_context         );      //     // these first 2 callbacks called @ dirql.  job     // enable , disable interrupts.     //     interruptconfig.evtinterruptenable  = tdvrevtinterruptenable;     interruptconfig.evtinterruptdisable = tdvrevtinterruptdisable;      // if driver calls wdfinterruptcreate evtdriverdeviceadd, interruptraw ,     // interrupttranslated members of wdf_interrupt_config structure must null.      // driver calls wdfinterruptcreate evtdevicepreparehardware, these members must both valid.     interruptconfig.interrupttranslated = interruptdesctranslated;     interruptconfig.interruptraw = interruptdescraw;      // our driver must call wdfinterruptcreate once each interrupt vector device requires.      // if device supports message-signaled interrupts (msi), driver must create interrupt object      // each message device can support.     status = wdfinterruptcreate(         devicecontext->wdfdevice,         &interruptconfig,         &interruptattributes,         &devicecontext->wdfinterrupt         );      if (!nt_success(status))     {         traceinterrupt(trace_level_error, "wdfinterruptcreate failed: %!status!\n", status);     }     else     {         pinterrupt_context interruptcontext = interruptgetcontext(devicecontext->wdfinterrupt);         // whatever context info     }      funcexit();     return status; } 

like said have figured out, thought post anyway contribute.


Comments

Popular posts from this blog

c# - Send Image in Json : 400 Bad request -

jquery - Fancybox - apply a function to several elements -

An easy way to program an Android keyboard layout app -