none
IoConnectInterruptEx() Returns 0xC000000BB - not supported RRS feed

  • Question

  • Hi,

    In AVStream example project, it simulates hardware interrupt. I want to setup MSI interrupt, so it becomes real.

    In PnpStart (), I try to use passed in PCM_RECSOURCE_LIST parameter to assign the resource for the driver and setup the interrupt by calling

    status = IoConnectInterruptEx(&iip); in the

    CCaptureDevice::AssignHWResources() function.

    But IoConnectInterruptEx returns 0xC000000BB - not supported error.

    I believe it is the

    IO_CONNECT_INTERRUPT_PARAMETERS ipp structure is not assigned with right values.

     Specifically: PhysicalDeviceObject, ConnectionContext.InterruptMessageTable, and ServiceContext:

    iip.MessageBased.PhysicalDeviceObject = (

    PDEVICE_OBJECT)m_Device;//?

    iip.MessageBased.ConnectionContext.Generic = (

    PVOID*)&p_msii;

    iip.MessageBased.ConnectionContext.InterruptMessageTable = ?;

    iip.MessageBased.ServiceContext = m_Device->FunctionalDeviceObject;

    //

    I posted code snippet here:

    NTSTATUS CCaptureDevice::PnpStart(IN PCM_RESOURCE_LIST TranslatedResourceList,

    IN PCM_RESOURCE_LIST UntranslatedResourceList) {

    PAGED_CODE();

    NTSTATUS Status = STATUS_SUCCESS;

    if(!m_Device->Started) { // Create the Filter for the device


    KsAcquireDevice(m_Device);

    Status = KsCreateFilterFactory(m_Device->FunctionalDeviceObject,

    &CaptureFilterDescriptor,

    L

    "GLOBAL",

    NULL,

    KSCREATE_ITEM_FREEONSTOP,

    NULL,

    NULL,

    NULL);

    KsReleaseDevice(m_Device);

    }

    // By PnP, it's possible to receive multiple starts without an intervening


    // stop (to reevaluate resources, for example).  Thus, we only perform


    // creations of the simulation on the initial start and ignore any


    // subsequent start.  Hardware drivers with resources should evaluate


    // resources and make changes on 2nd start.


    if(NT_SUCCESS(Status) && (!m_Device->Started)) {

    m_HardwareSimulation =

    new(NonPagedPool)CHardwareSimulation(this);

    //...


    Status = AssignHWResources(TranslatedResourceList);

    //...


    Status = KsAddItemToObjectBag(m_Device->Bag,

    reinterpret_cast<PVOID> (m_HardwareSimulation),

    reinterpret_cast<PFNKSFREE> (CHardwareSimulation::Cleanup));

    if(!NT_SUCCESS(Status)) {

    deletem_HardwareSimulation;

    }

    }

    returnStatus;

    }

     


    class

    CCaptureDevice : publicIHardwareSink {

    //...


    private

    :

    staticBOOLEAN InterruptService(IN struct_KINTERRUPT *Interrupt, IN PVOID ServiceContext,

    IN ULONG MessageID);

    //...


    }

    NTSTATUS CCaptureDevice::AssignHWResources(IN PCM_RESOURCE_LIST TranslatedResourceList) {

    NTSTATUS    status = STATUS_SUCCESS;

    BOOLEAN     bResPort = FALSE;

    BOOLEAN     bResInterrupt = FALSE;

    BOOLEAN     bResMemory = FALSE;

    ULONG       numberOfBARs = 0;

    for(ULONG i = 0; i < TranslatedResourceList->Count; i++){

    PCM_FULL_RESOURCE_DESCRIPTOR pfDesc;

    PCM_PARTIAL_RESOURCE_LIST ppList;

    PCM_PARTIAL_RESOURCE_DESCRIPTOR pDesc;

    pfDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)&(TranslatedResourceList->List[i]);

    ppList = (PCM_PARTIAL_RESOURCE_LIST)(&pfDesc->PartialResourceList);

    for(ULONG j = 0; j < ppList->Count; j++){

    pDesc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)&(ppList->PartialDescriptors[j]);

    switch(pDesc->Type) {

    caseCmResourceTypePort:

    break;

    caseCmResourceTypeMemory:

    break;

    caseCmResourceTypeInterrupt:

    //////////////////////////////////////////////////////


    // What kind of interrupt has been provided?


    if(CM_RESOURCE_INTERRUPT_MESSAGE & pDesc->Flags){

    Kdf_PrintEx((_DIID, _DIL,

    " MSI IRQ: Level=%X, Vector=%X, Cnt=%X\n",

    pDesc->u.MessageInterrupt.Translated.Level,

    pDesc->u.MessageInterrupt.Translated.Vector,

    pDesc->u.MessageInterrupt.Raw.MessageCount));

    }

    else{

    Kdf_PrintEx((_DIID, _DIL,

    " Legacy IRQ:Flag=%X, Vector=%X\n",

    pDesc->u.Interrupt.Level, pDesc->u.Interrupt.Vector));

    }

    //////////////////////////////////////////////////////


    IO_CONNECT_INTERRUPT_PARAMETERS iip;

    RtlZeroMemory(&iip,

    sizeof(IO_CONNECT_INTERRUPT_PARAMETERS));

    iip.Version = CONNECT_MESSAGE_BASED;

    PKMESSAGE_SERVICE_ROUTINE misr = (PKMESSAGE_SERVICE_ROUTINE)CCaptureDevice::InterruptService;

    PKSERVICE_ROUTINE isr = NULL;

    PIO_INTERRUPT_MESSAGE_INFO p_msii = NULL;

    misr =

    reinterpret_cast<PKMESSAGE_SERVICE_ROUTINE> (CCaptureDevice::InterruptService);

    iip.MessageBased.PhysicalDeviceObject = (PDEVICE_OBJECT)m_Device;

    //?


    iip.MessageBased.ConnectionContext.Generic = ; 

    //?


    iip.MessageBased.ConnectionContext.InterruptMessageTable = ;

    //?


    iip.MessageBased.ServiceContext = m_Device->FunctionalDeviceObject;

    iip.MessageBased.MessageServiceRoutine = misr;

    iip.MessageBased.FallBackServiceRoutine = NULL;

    iip.MessageBased.SynchronizeIrql = PASSIVE_LEVEL;

    iip.MessageBased.SpinLock = NULL;

    iip.MessageBased.FloatingSave = FALSE;

    status = IoConnectInterruptEx(&iip);

    if(NT_SUCCESS(status)) {

    }

    else{

    Kdf_PrintEx((_DIID, _DIL,

    "Failed=%X\n", status)); //Returns 0xC00000BB - Not Supported


    }

    break;

    default:

    break;

    }

    }

    }

    returnSTATUS_SUCCESS;

    }

    How to setup the

    IO_CONNECT_INTERRUPT_PARAMETERS iip

    structure?

    Thank you,

    Tiger

    Wednesday, July 8, 2015 6:48 PM

Answers

  • I had IRQ connected with the following code:

    IO_CONNECT_INTERRUPT_PARAMETERS iip;

    RtlZeroMemory(&iip,

    sizeof(IO_CONNECT_INTERRUPT_PARAMETERS));

    iip.Version = CONNECT_MESSAGE_BASED;

    iip.MessageBased.PhysicalDeviceObject = (PDEVICE_OBJECT)m_Device->PhysicalDeviceObject;

    iip.MessageBased.ConnectionContext.Generic = (PVOID *)&p_msii;

    iip.MessageBased.ServiceContext = m_Device->Context;

    iip.MessageBased.MessageServiceRoutine =

    reinterpret_cast<PKMESSAGE_SERVICE_ROUTINE> (MSI_isr);

    iip.MessageBased.FallBackServiceRoutine =

    reinterpret_cast<PKSERVICE_ROUTINE> (ISR_isr);

    iip.MessageBased.SynchronizeIrql = PASSIVE_LEVEL;

    iip.MessageBased.SpinLock = NULL;

    iip.MessageBased.FloatingSave = FALSE;

    status = IoConnectInterruptEx(&iip);


    if

    (NT_SUCCESS(status)) {

    //connected


    }

    It got successfully connected at this point.

    Thank you,

    Tiger

    Thursday, July 9, 2015 1:26 PM

All replies

  • Am I interpreting this correctly, "are you trying to get an MSI interrupt without actually having a device that supports MSI?"  If so stop now this will not work.

    My other question is did you add the correct settings to the INF file, see https://msdn.microsoft.com/en-us/library/windows/hardware/ff544246(v=vs.85).aspx to enable MSI interrupts?


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Wednesday, July 8, 2015 6:55 PM
  • The physical device is PCIe device. PCIe device itself supports MSI. I had this driver working. In the AVStream, the device is created through :

    CCaptureDevice

    ::DispatchCreate();

    In the

    NTSTATUS

    CCaptureDevice::PnpStart (INPCM_RESOURCE_LISTTranslatedResourceList,

       

    INPCM_RESOURCE_LISTUntranslatedResourceList)

    The TranslatedResourceList contains all the PCIe resources, such as MemoryBar addresses, MSI interrupts, etc. All the PCIe driver resource is in the list, including MSI. But the problem I have the message interrupt structures are different between

    iip.MessageBased.ConnectionContext.InterruptMessageTable and

    pDesc->u.MessageInterrupt (contains

    Translated.Level, Translated.Vector, Raw.MessageCount).

    If the CCaptureDevice::m_Device (a pointer of PKSDevice) has

    FunctionalDeviceObject and MemoryBars, and MSI, why it cannot be cascaded to,

    although I don't know the answer?

    Thank you,

    Tiger

    Wednesday, July 8, 2015 7:11 PM
  • I had IRQ connected with the following code:

    IO_CONNECT_INTERRUPT_PARAMETERS iip;

    RtlZeroMemory(&iip,

    sizeof(IO_CONNECT_INTERRUPT_PARAMETERS));

    iip.Version = CONNECT_MESSAGE_BASED;

    iip.MessageBased.PhysicalDeviceObject = (PDEVICE_OBJECT)m_Device->PhysicalDeviceObject;

    iip.MessageBased.ConnectionContext.Generic = (PVOID *)&p_msii;

    iip.MessageBased.ServiceContext = m_Device->Context;

    iip.MessageBased.MessageServiceRoutine =

    reinterpret_cast<PKMESSAGE_SERVICE_ROUTINE> (MSI_isr);

    iip.MessageBased.FallBackServiceRoutine =

    reinterpret_cast<PKSERVICE_ROUTINE> (ISR_isr);

    iip.MessageBased.SynchronizeIrql = PASSIVE_LEVEL;

    iip.MessageBased.SpinLock = NULL;

    iip.MessageBased.FloatingSave = FALSE;

    status = IoConnectInterruptEx(&iip);


    if

    (NT_SUCCESS(status)) {

    //connected


    }

    It got successfully connected at this point.

    Thank you,

    Tiger

    Thursday, July 9, 2015 1:26 PM