⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 irfir.cpp

📁 freescale i.mx31 BSP CE5.0全部源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        *BytesNeeded = 0;

        NdisAcquireSpinLock(&thisDev->Lock);

        switch (Oid)
        {
            case OID_IRDA_LINK_SPEED:
                info = *(UINT *)InformationBuffer;
                DEBUGMSG(ZONE_SETINFO, (TEXT("IrFir: IrFirSetInformation(OID_IRDA_LINK_SPEED, %d)\r\n"), info));
                result = NDIS_STATUS_INVALID_DATA;

                for (int i = 0; i < NUM_BAUDRATES; i++)
                {
                    if (supportedBaudRateTable[i].bitsPerSec == info)
                    {
                        thisDev->newSpeed = supportedBaudRateTable[i].bitsPerSec;
                        result = NDIS_STATUS_SUCCESS;
                        break;
                    }
                }
                if (result == NDIS_STATUS_SUCCESS)
                {
                    if (!SetSpeed(thisDev))
                        result = NDIS_STATUS_FAILURE;
                }
                else
                {
                    result = NDIS_STATUS_FAILURE;
                    *BytesRead = 0;
                    *BytesNeeded = 0;
                }
                break;

            case OID_IRDA_MEDIA_BUSY:
                info = *(UINT *)InformationBuffer;
                DEBUGMSG(ZONE_SETINFO, (TEXT("IrFir: IrFirSetInformation(OID_IRDA_MEDIA_BUSY, %xh)\r\n"), info));

                //  The protocol can use this OID to reset the busy field
                //  in order to check it later for intervening activity.
                thisDev->mediaBusy = (BOOLEAN)info;
                result = NDIS_STATUS_SUCCESS;
                break;

            case OID_IRDA_REACQUIRE_HW_RESOURCES:
                DEBUGMSG(ZONE_SETINFO, (TEXT("IrFir: IRDA: Set(OID_IRDA_REACQUIRE_HW_RESOURCES)\r\n")));
				*BytesNeeded = 0;

                if (thisDev->resourcesReleased == FALSE)
                {
                    DEBUGMSG(ZONE_WARN, (TEXT("IrFir: IRDA: resources already acquired!!\r\n")));
                    result = NDIS_STATUS_FAILURE;
                }
                else
                {
                    if (thisDev->IR_VTbl->m_pAcquireAdapterResources(thisDev))
                    {
						// Reset state.
						thisDev->portInfo.rcvState = STATE_INIT;
						thisDev->writePending = FALSE;
                        thisDev->resourcesReleased = FALSE;
                        // Setup receive
                        thisDev->IR_VTbl->m_pSetupRecv(thisDev);
                    }
                    else
                    {
                        DEBUGMSG(ZONE_ERROR, (TEXT("IrFir: IRDA: initialization failure.\r\n")));
                        result = NDIS_STATUS_FAILURE;
                    }
                }
                break;

            case OID_GEN_CURRENT_PACKET_FILTER:
                DEBUGMSG(ZONE_SETINFO, (TEXT("IrFir: IrFirSetInformation(OID_GEN_CURRENT_PACKET_FILTER)\r\n")));
                result = NDIS_STATUS_SUCCESS;
                break;

            // Power management related OID's
            case OID_PNP_SET_POWER:
                DEBUGMSG(ZONE_SETINFO, (TEXT("IrFir: IrFirSetInformation(OID_PNP_SET_POWER)\r\n")));
                if (InformationBufferLength != sizeof(NDIS_DEVICE_POWER_STATE ))
                {
                    return(NDIS_STATUS_INVALID_LENGTH);
                }
                NewPowerState = *(PNDIS_DEVICE_POWER_STATE)InformationBuffer;
                if(NewPowerState != NdisDeviceStateD0)
                   NewPowerState = NdisDeviceStateD3; 
                // Set the power state - Cannot fail this request
                if(NewPowerState == NdisDeviceStateD0)
                {
                    // Power ON
                    thisDev->IR_VTbl->m_pAcquireAdapterResources(thisDev);
                }
                else
                {
                    // Power OFF
                    thisDev->IR_VTbl->m_pReleaseAdapterResources(thisDev);
                }
                *BytesRead = sizeof(NDIS_DEVICE_POWER_STATE);
                result = NDIS_STATUS_SUCCESS; 
                break;
            // we dont need to support these                
            case OID_PNP_ADD_WAKE_UP_PATTERN:
            case OID_PNP_REMOVE_WAKE_UP_PATTERN:
            case OID_PNP_ENABLE_WAKE_UP:
            // We don't support these
            case OID_IRDA_RATE_SNIFF:
            case OID_IRDA_UNICAST_LIST:

            // These are query-only parameters.
            case OID_IRDA_SUPPORTED_SPEEDS:
            case OID_IRDA_MAX_UNICAST_LIST_SIZE:
            case OID_IRDA_TURNAROUND_TIME:

            default:
                DEBUGMSG(ZONE_SETINFO, (TEXT("IrFir: IrFirSetInformation(OID=%d=0x%x) - unsupported OID\r\n"), Oid, Oid));
                *BytesRead = 0;
                *BytesNeeded = 0;
                result = NDIS_STATUS_NOT_SUPPORTED;
                break;
        }

        NdisReleaseSpinLock(&thisDev->Lock);
    }
    else
    {
        *BytesRead = 0;
        *BytesNeeded = sizeof(UINT);
        result = NDIS_STATUS_INVALID_LENGTH;
    }

    if(result == NDIS_STATUS_SUCCESS)
        DEBUGMSG(ZONE_SETINFO, (TEXT("IrFir: IrFirSetInformation succeeded\r\n")));
    else
        DEBUGMSG(ZONE_WARN, (TEXT("IrFir: IrFir: IrFirSetInformation failed\r\n")));

    return result;
}


//-----------------------------------------------------------------------------
//
// Function: IrFirReturnPacket
//
//  When NdisMIndicateReceivePacket returns asynchronously, the protocol returns ownership
//  of the packet to the miniport via this function.
//
// Parameters:
//      MiniportAdapterContext
//          [in] .
//      Packet
//          [in] .
//
// Returns:
//      None.
//
//-----------------------------------------------------------------------------
VOID IrFirReturnPacket( NDIS_HANDLE MiniportAdapterContext, PNDIS_PACKET Packet )
{
    pFirDevice_t thisDev = (pFirDevice_t)MiniportAdapterContext;
    rcvBuffer *rcvBuf;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("IrFir: IrFirReturnPacket(0x%x, packet = 0x%x)\r\n"), (UINT)MiniportAdapterContext, Packet));

    NdisAcquireSpinLock(&thisDev->Lock);

    // MiniportReserved contains the pointer to our rcvBuffer
    rcvBuf = *(rcvBuffer**) Packet->MiniportReserved;

    if (rcvBuf->state == STATE_PENDING)
    {
        PNDIS_BUFFER ndisBuf;

        DEBUGMSG(ZONE_FUNCTION, (TEXT("IrFir: Reclaimed rcv packet 0x%x.\r\n"), (UINT)Packet));
        NdisUnchainBufferAtFront(Packet, &ndisBuf);

        if (ndisBuf)
            NdisFreeBuffer(ndisBuf);

        // At SIR speeds, we manage a group of buffers that
        // we keep on the rcvBufBuf queue.

        InsertTailList(&thisDev->rcvBufBuf, RCV_BUF_TO_LIST_ENTRY(rcvBuf->dataBuf));

        rcvBuf->dataBuf = NULL;
        rcvBuf->state = STATE_FREE;

        RemoveEntryList(&rcvBuf->listEntry);
        InsertHeadList(&thisDev->rcvBufFree, &rcvBuf->listEntry);
    }
    else
        DEBUGMSG(ZONE_FUNCTION, (TEXT("IrFir: Packet in IrFirReturnPacket was not PENDING\r\n")));

    NdisReleaseSpinLock(&thisDev->Lock);
}


//-----------------------------------------------------------------------------
//
// Function: DeliverFullBuffers
//
//  This function delivers received packets to the protocol.
//
// Parameters:
//      thisDev
//          [in] pointer to Fir Device structure.
//
// Returns:
//      This function returns TRUE if delivered at least one frame
//
//-----------------------------------------------------------------------------
BOOLEAN DeliverFullBuffers( pFirDevice_t thisDev )
{
    BOOLEAN result = FALSE;
    PLIST_ENTRY ListEntry;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("IrFir: +DeliverFullBuffers(0x%x)\r\n"), (UINT) thisDev));

    // Deliver all full rcv buffers
    for (ListEntry = MyRemoveHeadList(&thisDev->rcvBufFull); ListEntry;
        ListEntry = MyRemoveHeadList(&thisDev->rcvBufFull))
    {
        rcvBuffer *rcvBuf = CONTAINING_RECORD(ListEntry, rcvBuffer, listEntry);

        NDIS_STATUS stat;
        PNDIS_BUFFER packetBuf;
        SLOW_IR_FCS_TYPE fcs;

        if (thisDev->linkSpeedInfo->bitsPerSec <= MAX_SIR_SPEED)
        {
            // The packet we have already has had BOFs,
            // EOF, and * escape-sequences removed.  It
            // contains an FCS code at the end, which we
            // need to verify and then remove before
            // delivering the frame.  We compute the FCS
            // on the packet with the packet FCS attached;
            // this should produce the constant value
            // GOOD_FCS.
            fcs = ComputeFCS(rcvBuf->dataBuf, rcvBuf->dataLen);

            if (fcs != GOOD_FCS)
            {
                //  FCS Error.  Drop this frame.
                DEBUGMSG(ZONE_FUNCTION, (TEXT("IrFir: Bad FCS in DeliverFullBuffers bad != good 0x%x!=0x%x.\r\n"), (UINT)fcs, (UINT) GOOD_FCS));
                rcvBuf->state = STATE_FREE;

                DEBUGMSG(ZONE_FUNCTION, (TEXT("IrFir: Dropped pkts; BAD FCS (%xh!=%xh):\r\n"), fcs, GOOD_FCS));

                InsertTailList(&thisDev->rcvBufBuf, RCV_BUF_TO_LIST_ENTRY(rcvBuf->dataBuf));
                rcvBuf->dataBuf = NULL;

                InsertHeadList(&thisDev->rcvBufFree, &rcvBuf->listEntry);
                //break;
                continue;
            }

            // Remove the FCS from the end of the packet
            rcvBuf->dataLen -= SLOW_IR_FCS_SIZE;
        }

        // The packet array is set up with its NDIS_PACKET.
        // Now we need to allocate a single NDIS_BUFFER for
        // the NDIS_PACKET and set the NDIS_BUFFER to the
        // part of dataBuf that we want to deliver.
        NdisAllocateBuffer(&stat, &packetBuf, thisDev->bufferPoolHandle,
            (PVOID)rcvBuf->dataBuf, rcvBuf->dataLen);

        if (stat != NDIS_STATUS_SUCCESS)
        {
            DEBUGMSG(ZONE_ERROR, (TEXT("IrFir: NdisAllocateBuffer failed\r\n")));
            break;
        }

        NdisChainBufferAtFront(rcvBuf->packet, packetBuf);

        // Fix up some other packet fields.
        NDIS_SET_PACKET_HEADER_SIZE(rcvBuf->packet, IR_ADDR_SIZE+IR_CONTROL_SIZE);

        DEBUGMSG(ZONE_FUNCTION, (TEXT("IrFir: Indicating rcv packet 0x%x.\r\n"), (UINT)rcvBuf->packet));

        // Indicate to the protocol that another packet is
        // ready.  Set the rcv buffer's state to PENDING first
        // to avoid a race condition with NDIS's call to the
        // return packet handler.
        rcvBuf->state = STATE_PENDING;

        *(rcvBuffer **)rcvBuf->packet->MiniportReserved = rcvBuf;
        InsertBufferSorted(&thisDev->rcvBufPend, rcvBuf);

        NdisReleaseSpinLock(&thisDev->Lock);
        NdisMIndicateReceivePacket(thisDev->ndisAdapterHandle, &rcvBuf->packet, 1);
        NdisAcquireSpinLock(&thisDev->Lock);

        result = TRUE;

        stat = NDIS_GET_PACKET_STATUS(rcvBuf->packet);

        if (stat == NDIS_STATUS_PENDING)
        {
            // The packet is being delivered asynchronously.
            // Leave the rcv buffer's state as PENDING;
            // we'll get a callback when the transfer is
            // complete.  Do NOT step firstRcvBufIndex.
            // We don't really need to break out here,
            // but we will anyways just to make things
            // simple.  This is ok since we get this
            // deferred interrupt callback for each packet
            // anyway.  It'll give the protocol a chance
            // to catch up.
            DEBUGMSG(ZONE_FUNCTION, (TEXT("IrFir: DeliverFullBuffers, Rcv Pending. Rcvd packets\r\n")));
        }
        else
        {
            // If there was an error, we are dropping this
            // packet; otherwise, this packet was delivered
            // synchronously.  We can free the packet
            // buffer and make this rcv frame available.
            RemoveEntryList(&rcvBuf->listEntry);

            NdisUnchainBufferAtFront(rcvBuf->packet, &packetBuf);
            if (packetBuf)
                NdisFreeBuffer(packetBuf);

            rcvBuf->state = STATE_FREE;

            // At SIR speeds, we manage a group of buffers that
            // we keep on the rcvBufBuf queue.
            InsertTailList(&thisDev->rcvBufBuf, RCV_BUF_TO_LIST_ENTRY(rcvBuf->dataBuf));

            rcvBuf->dataBuf = NULL;

            InsertHeadList(&thisDev->rcvBufFree, &rcvBuf->listEntry);

            if (stat == NDIS_STATUS_SUCCESS)
            {
                DEBUGMSG(ZONE_FUNCTION, (TEXT("IrFir: DeliverFullBuffers, Rcvd packets\r\n")));
            }
            else
            {
                DEBUGMSG(ZONE_FUNCTION, (TEXT("IrFir: DeliverFullBuffers, Dropped rcv packets.\r\n")));
            }
        }
    }

    DEBUGMSG(ZONE_FUNCTION, (TEXT("IrFir: -DeliverFullBuffers\r\n")));
    return result;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -