コード例 #1
0
ファイル: hvl_main.c プロジェクト: 340211173/Driver
NDIS_STATUS
Hvl11DeregisterHelperPort(
    _In_  PHVL    pHvl,
    _In_  PVNIC   pVNic
    )
{
    NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS;

    UNREFERENCED_PARAMETER(pVNic);

    ASSERT(HvlIsHelperVNic(pHvl, pVNic));
    
    HvlLock(pHvl);

    HvlRemoveVNicFromCtx(pHvl, pVNic);

    HvlUnlock(pHvl);
    
    return ndisStatus;
}
コード例 #2
0
ファイル: hvl_queue.c プロジェクト: Realhram/wdk81
NDIS_STATUS
HvlQueueExAccessRequest(
    _In_  PHVL                    pHvl,
    _In_  PVNIC                   pVNic,
    _In_  BOOLEAN                 fPnpOperation
    )
{
    NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS;
    PHVL_EX_ACCESS_REQ pExReq = NULL, pPnpExReq = NULL;
    PHVL_PENDING_OP pPendingOp = NULL;

    ASSERT(HvlIsLocked(pHvl));
    
    do
    {
        // All requests by the helper port are considered different
        if (!HvlIsHelperVNic(pHvl, pVNic))
        {
            /*
                Does an exclusive access request for this VNIC already exist?
                */
            pExReq = HvlGetNextReqForVNic(pHvl, pVNic, FALSE);
        }

        if (NULL != pExReq)
        {
            /*
                There is already an exclusive access request existing for this VNIC. 
                */

            /*
                If the request is not a PnP request simply ref-up
                */
            if (!HvlIsPreAllocatedRequest(pHvl, pExReq))
            {
                pExReq->ulRefCount++;
                MpTrace(COMP_HVL, DBG_NORMAL, ("VNIC (%d): Incremented refcount for an exclusive access requet. New ref = %d \n", VNIC_PORT_NO, pExReq->ulRefCount));
            }
            else
            {
                /*
                    a request already exists. However it is the PnP request. Make sure we do 
                    not use it for non-Pnp operation. If we did, we might get another PnP 
                    operation after this PnP operation is done but we won't be able to use the
                    pre-allocated request. Instead try to allocate a new request now
                    */

                // pnp operations must be serialized
                ASSERT(!fPnpOperation);

                pPnpExReq = pExReq;
                pExReq = NULL;

                // allocate exclusive access request                
                ndisStatus = ALLOC_MEM(pHvl->MiniportAdapterHandle, sizeof(HVL_EX_ACCESS_REQ), &pExReq);
                if (NDIS_STATUS_SUCCESS != ndisStatus)
                {
                    MpTrace(COMP_HVL, DBG_SERIOUS, ("Failed to allocate memory for a new exclusive access request\n"));
                    break;
                }

                // allocate pending operation
                ndisStatus = ALLOC_MEM(pHvl->MiniportAdapterHandle, sizeof(HVL_PENDING_OP), &pPendingOp);
                if (NDIS_STATUS_SUCCESS != ndisStatus)
                {
                    MpTrace(COMP_HVL, DBG_SERIOUS, ("Failed to allocate memory for a new pending operation"));
                    break;
                }
                
                pExReq->pVNic = pVNic;
                pExReq->ulRefCount = pPnpExReq->ulRefCount + 1;

                pPendingOp->Type = HVL_PENDING_OP_EX_ACCESS;
                pPendingOp->pvOpData= pExReq;

                // now insert this new request in the same place as the old request
                pPendingOp->Link.Flink = pHvl->PnpPendingOp.Link.Flink;
                pPendingOp->Link.Blink = pHvl->PnpPendingOp.Link.Blink;
                pHvl->PnpPendingOp.Link.Flink->Blink = &pPendingOp->Link;
                pHvl->PnpPendingOp.Link.Blink->Flink = &pPendingOp->Link;

                // re-init the pre-allocated request since we are no longer using it
                HvlInitPreAllocatedOp(pHvl);
            }
        }
        else
        {
            /*
                This is the only exclusive access request for the HVL. Create a new request
                */
            if (fPnpOperation)
            {
                ASSERT(pHvl->PnpPendingOp.Link.Blink == NULL && pHvl->PnpPendingOp.Link.Flink == NULL);
                
                pExReq = pHvl->pPnpOpExReq;
            }
            else
            {
                ndisStatus = ALLOC_MEM(pHvl->MiniportAdapterHandle, sizeof(HVL_EX_ACCESS_REQ), &pExReq);
                if (NDIS_STATUS_SUCCESS != ndisStatus)
                {
                    MpTrace(COMP_HVL, DBG_SERIOUS, ("Failed to allocate memory for a new exclusive access request\n"));
                    break;
                }
            }
            
            pExReq->pVNic = pVNic;
            pExReq->ulRefCount = 1;

            ndisStatus = HvlQueuePendingOperation(pHvl, HVL_PENDING_OP_EX_ACCESS, pExReq, fPnpOperation);
            if (NDIS_STATUS_SUCCESS != ndisStatus)
            {
                MpTrace(COMP_HVL, DBG_SERIOUS, ("HvlQueuePendingOperation failed 0x%x\n", ndisStatus));
                break;
            }
            
            MpTrace(COMP_HVL, DBG_NORMAL, ("Queued an exclusive access requet for VNIC (%d)\n", VNIC_PORT_NO));
        }
    } while (FALSE);

    if (NDIS_FAILURE(ndisStatus))
    {
        if (pExReq && !fPnpOperation)
        {
            HvlDeleteExAccessRequest(pHvl, pExReq);
        }

        if (pPendingOp)
        {
            FREE_MEM(pPendingOp);
        }
    }
    
    return ndisStatus;
}
コード例 #3
0
ファイル: hvl_main.c プロジェクト: 340211173/Driver
NDIS_STATUS
Hvl11ReleaseExAccess(PHVL pHvl, PVNIC pVNic)
{
    NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS;
    PVNIC pExVNic = NULL;
    PHVL_EX_ACCESS_REQ pExReq = NULL;
    
    MpTrace(COMP_HVL, DBG_NORMAL, ("VNic(%d) releasing exclusive access\n", VNIC_PORT_NO));

    HvlLock(pHvl);

    pExReq = HvlDequeueNextReqForVNic(pHvl, pVNic);
    
    if (pExReq && 0 == pExReq->ulRefCount)
    {
        /*
            This is the last release by this VNIC. Actually take away exclusive access if this is 
            the current owner of exclusive access
            */
        pExVNic = HvlGetExAccessVNic(pHvl);
        
        if (pExVNic == pVNic)
        {
            MpTrace(COMP_HVL, DBG_NORMAL, ("VNic(%d) currently owns exclusive access. Giving it up and removing it from the queue\n", VNIC_PORT_NO));
            
            HvlReleaseExAccess(pHvl, pVNic);    

            // set the event so that some other VNIC waiting for access can now get it
            KeSetEvent(&pHvl->ExAccessEvent, 0, FALSE);   
        }
        else
        {
            /*
                The VNIC is releasing exclusive access even when it doesn't own it. This can
                happen - take for example the following
                1. There is a helper port and an extensible station port
                2. A Pause is happening and the helper port has exclusive access.
                3. The station asks its VNIC to perform a dot11 reset
                4. The station's VNIC requests exclusive access. Since the helper port has it, its request is queued
                5. The helper port activates the station as part of its Pause processing
                6. The station VNIC's CtxSToVNic is called and the VNIC learns it has exclusive access
                7. The station VNIC completes its reset operation and asks Hvl to release exclusive access
                8. The calls comes into the HVL and we would land up in this else clause.

                The correct thing to do here is to simply remove the station VNIC's request from
                the queue which is what we have done here
                */
            MpTrace(COMP_HVL, DBG_NORMAL, ("VNic(%d) doesn't own exclusive access currently. Just removing it from the queue\n", VNIC_PORT_NO));

            if (NULL == pExVNic)
            {
                //no one has exclusive access right now. set the event so that some other 
                //VNIC waiting for access can now get it
                KeSetEvent(&pHvl->ExAccessEvent, 0, FALSE);
            }
        }

        // delete the request
        if (HvlIsPreAllocatedRequest(pHvl, pExReq))
        {
            // it is a pre-allocated request - simply reset it
            HvlInitPreAllocatedOp(pHvl);
        }
        else
        {
            HvlDeleteExAccessRequest(pHvl, pExReq);        
        }
    }
    else
    {
        ASSERT(!HvlIsHelperVNic(pHvl, pVNic));
        
        /*
            This VNIC has more requests for exclusive access pending
            */
        MpTrace(COMP_HVL, DBG_NORMAL, ("VNic(%d) has %d more exclusive access requests. Decremented the refcount. Not removing it from the queue\n", VNIC_PORT_NO, pExReq ? pExReq->ulRefCount : -1));
        ndisStatus = NDIS_STATUS_PENDING;        
    }
    
    HvlUnlock(pHvl);

    return ndisStatus;
}
コード例 #4
0
ファイル: hvl_main.c プロジェクト: 340211173/Driver
NDIS_STATUS
Hvl11RequestExAccess(
    _In_ PHVL pHvl, 
    _In_ PVNIC pVNic,
    _In_ BOOLEAN fPnPOperation
    )
{
    NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS;
    BOOLEAN fLocked = FALSE;
    
    do
    {
        HvlLock(pHvl);
        fLocked = TRUE;
        
        ndisStatus = HvlQueueExAccessRequest(pHvl, pVNic, fPnPOperation);
        if (NDIS_STATUS_SUCCESS != ndisStatus)
        {
            MpTrace(COMP_HVL, DBG_SERIOUS, ("HvlQueueExAccessRequest failed 0x%x", ndisStatus));
            break;
        }

        // now determine the return status to be given to the VNIC. 
        if (pHvl->pExAccessDelegatedVNic)
        {            
            // if the helper port has delegated exclusive access to some VNIC, new request 
            // by only that VNIC can succeed. Everyone else, including the helper port, should
            // wait
            if (pHvl->pExAccessDelegatedVNic == pVNic)
            {
                MpTrace(COMP_HVL, DBG_NORMAL, ("VNic (%d) has already been delegated exclusive access. Completing its request for exclusive access inline. \n", VNIC_PORT_NO));
                ndisStatus = NDIS_STATUS_SUCCESS;
            }
            else
            {
                ndisStatus = NDIS_STATUS_PENDING;
                MpTrace(COMP_HVL, DBG_NORMAL, ("VNic (%d) has been delegated exclusive access. Pending VNic(%d)'s request for exclusive access.\n", pHvl->pExAccessDelegatedVNic->PortNumber, VNIC_PORT_NO));
            }
        }
        else
        {
            if (HvlGetExAccessVNic(pHvl) == pVNic)
            {
                if (HvlIsHelperVNic(pHvl, pVNic))
                {
                    // helper port never gets exclusive access inline
                    MpTrace(COMP_HVL, DBG_NORMAL, ("Helper VNic (%d) has exclusive access. Still pending VNic(%d)'s exclusive access request \n", pHvl->pExAccessVNic->PortNumber, VNIC_PORT_NO));
                    ndisStatus = NDIS_STATUS_PENDING;
                }
                else
                {
                    // let the VNIC know that it already has exclusive access
                    MpTrace(COMP_HVL, DBG_NORMAL, ("VNic (%d) already has exclusive access. Completing its request for exclusive access inline. \n", VNIC_PORT_NO));
                    ndisStatus = NDIS_STATUS_SUCCESS;
                }
            }
            else if (HvlGetExAccessVNic(pHvl))
            {
                // the VNIC will get exclusive access later
                MpTrace(COMP_HVL, DBG_NORMAL, ("VNic (%d) has exclusive access. Pending VNic(%d)'s exclusive access request \n", pHvl->pExAccessVNic->PortNumber, VNIC_PORT_NO));
                ndisStatus = NDIS_STATUS_PENDING;
            }
            else
            {
                // the VNIC will get exclusive access later
                MpTrace(COMP_HVL, DBG_NORMAL, ("No VNic has exclusive access. Pending VNic(%d)'s exclusive access request \n", VNIC_PORT_NO));
                ndisStatus = NDIS_STATUS_PENDING;
            }
        }
    } while (FALSE);

    if (fLocked)
    {
        HvlUnlock(pHvl);
    }
    
    if (NDIS_STATUS_PENDING == ndisStatus)
    {
        KeSetEvent(&pHvl->ExAccessEvent, 0, FALSE);
    }
    
    return ndisStatus;
}