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

📄 receive.c

📁 HomePNA的Usb网卡驱动
💻 C
字号:
/*++

Copyright (c) 1999  Microsoft Corporation

Module Name:

    receive.c  | usb NDIS Miniport Driver

Abstract:

    receive logic

Environment:

    kernel mode only

Notes:

  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  PURPOSE.

  Copyright (c) 1999 Microsoft Corporation.  All Rights Reserved.


Revision History:

--*/

#define BINARY_COMPATIBLE 1 // for win9x compatibility with ndis.h

#define DOBREAKS    // enable debug breaks

#include <ndis.h>
#include <ntddndis.h>  // defines OID's

#include "debug.h"
#include "common.h"
#include "usbndis.h"

/*****************************************************************************
*
*  Function:   ProcessData
*
*  Synopsis:   Copy our data to the appropriate buffer ,process
*              the USB header,  check for overrun,
*              deliver to the protocol
*
*  Arguments:  Device     - a pointer to the current ir device object
*              pRecBuf      - a pointer to a RCV_BUFFER struct
*
*  Returns:    STATUS_SUCCESS
*
*
*****************************************************************************/
NTSTATUS
ProcessData(
            IN PUSB_DEVICE        Device,
            IN PRCV_BUFFER      pRecBuf
            )
{
    //UCHAR    inboundHeader;
    NTSTATUS status = STATUS_SUCCESS;

    USB_DUMP( DBG_BUF,( pRecBuf->dataBuf,  pRecBuf->dataLen ) );


    //if ( pRecBuf->dataLen > Device->dongleCaps.dataSize + USB_USB_TOTAL_NON_DATA_SIZE )
    //{
        //
        // Reset the buffer for our next read.
        //
      //  Device->packetsReceivedOverflow++;
        //goto done;
    //}


    //inboundHeader = pRecBuf->dataBuf[0];


    // if fMediaBusy has been reset to 0 since last indication, set it

    /*if (  inboundHeader & INBOUND_HEADER_MEDIA_BUSY_BIT )
    {

        if ( FALSE == Device->fIndicatedMediaBusy )
        {
            InterlockedExchange( &Device->fMediaBusy, TRUE );
            InterlockedExchange( &Device->fIndicatedMediaBusy, TRUE );
            IndicateMediaBusy( Device );
        }
    }

    if ( pRecBuf->dataLen == 1 ){ // if no frame, link speed must be 0 ,bridge doc 5.4.1.2

        if ( 0 != ( inboundHeader & HEADER_LINK_SPEED_MASK )) {

            DEBUGMSG( DBG_ERR, ("   ( 0 != ( inboundHeader & HEADER_LINK_SPEED_MASK )) && ( pRecBuf->dataLen ==1 )\n"));
            ASSERT( 0 ); // bridge doc says this must be 0 if got header with no frame
        }
    }

    // we don't deliver the header to the protocol

    if ( pRecBuf->dataLen == 1 ) { // all we got was the header; this is possible
        goto done;

    }*/


    //
    // DeliverBuffer attempts to deliver the current
    // frame . If the ownership
    // of the packet is retained by the protocol, the
    // DeliverBuffer routine gives us a new receive
    // buffer.
    //

    status = DeliverBuffer(
                    Device,
                    pRecBuf
                    );


//done:
    DEBUGMSG(DBG_FUNC, ("-ProcessData\n"));

    return status;
}

/*****************************************************************************
*
*  Function:   MiniportReturnPacket
*
*  Synopsis:   The protocol returns ownership of a receive packet to
*              the usb device object.
*
*  Arguments:  Context         - a pointer to the current usb device obect.
*              pReturnedPacket - a pointer the packet which the protocol
*                                is returning ownership.
*
*  Returns:    None.
*
*
*
*****************************************************************************/
VOID
MiniportReturnPacket(
            IN NDIS_HANDLE  Context,
            IN PNDIS_PACKET pReturnedPacket
            )
{
    PUSB_DEVICE   device;
    PNDIS_BUFFER pBuffer;
    PRCV_BUFFER  pRecBuffer;
    UINT         Index;
    BOOLEAN      found = FALSE;


    DEBUGONCE(DBG_FUNC, ("+MiniportReturnPacket\n"));
    //
    // The context is just the pointer to the current ir device object.
    //

    device = CONTEXT_TO_DEV(Context);

    NdisInterlockedIncrement( (PLONG) &device->packetsReceived);

    //
    // Sear
    //ch the queue to find the right packet.

    for(Index=0;Index < NUM_RCV_BUFS;Index ++)
	{
        pRecBuffer = &(device->rcvBufs[Index]);

        if( ((PNDIS_PACKET) pRecBuffer->packet) ==  pReturnedPacket )
		{
            ProcessReturnPacket(device, pRecBuffer);
            found = TRUE;
            break;
        }
    }

    //
    // Ensure that the packet was found.
    //

    ASSERT( found );


    DEBUGMSG(DBG_FUNC, ("-MiniportReturnPacket\n"));

    return;
}

VOID ProcessReturnPacket(PUSB_DEVICE Device,
                         PRCV_BUFFER pReceiveBuffer)
{
    PNDIS_BUFFER pBuffer;

    DEBUGONCE(DBG_FUNC, ("+ProcessReturnPacket\n"));


    NdisUnchainBufferAtFront( (PNDIS_PACKET) pReceiveBuffer->packet, &pBuffer);

    ASSERT( pBuffer );

    if (pBuffer) {
        NdisFreeBuffer( pBuffer );
    }

    
    InterlockedExchange( &pReceiveBuffer->dataLen, 0);

    InterlockedExchange( (PULONG)&pReceiveBuffer->state, STATE_FREE);

    DEBUGMSG(DBG_FUNC, ("-ProcessReturnPacket\n"));

}
PRCV_BUFFER GetRcvBuf(
            PUSB_DEVICE Device,
               OUT UINT *pIndex,
      IN rcvBufferState state  // state to set to if found
                      )
{
    UINT    Index;
    PRCV_BUFFER pBuf = NULL;

    DEBUGMSG(DBG_FUNC, (" +GetRcvBuf()\n"));


    for(Index=0;Index < NUM_RCV_BUFS; Index++)
	{
        if( Device->rcvBufs[Index].state == STATE_FREE )
		{
            InterlockedExchange( (PULONG)&Device->rcvBufs[Index].state, (ULONG)state ); // set to input state

            *pIndex = Index;//RcvBuff number

            InterlockedExchange(  &Device->RcvBuffersInUse, Index+1);

            pBuf = &(Device->rcvBufs[*pIndex]);

            break;
        }
    }

    DEBUGMSG(DBG_FUNC, (" -GetRcvBuf()\n"));

    return pBuf;
}


/*****************************************************************************
*
*  Function:   DeliverBuffer
*
*  Synopsis:   Delivers the buffer to the protocol via
*              NdisMIndicateReceivePacket.
*
*  Arguments:  Device - pointer to the current ir device object
*
*  Returns:    STATUS_SUCCESS      - on success
*              STATUS_UNSUCCESSFUL - if packet can't be delivered to protocol
*
*
*
*****************************************************************************/

NTSTATUS
DeliverBuffer(
            IN  PUSB_DEVICE Device,
            IN  PRCV_BUFFER pRecBuf
            )
{
    PNDIS_BUFFER    pBuffer;
    NTSTATUS        status = STATUS_SUCCESS;
    PNDIS_BUFFER    Buffer;
    NDIS_STATUS        Status;

    NdisAllocateBuffer(
        &Status,
        &Buffer,
        Device->hBufferPool,
        pRecBuf->dataBuf,  // don't give header to protocol
        pRecBuf->dataLen  // don't give header to protocol
        );
    
    NdisChainBufferAtFront( (PNDIS_PACKET) pRecBuf->packet, Buffer);

    //
    // Fix up some other packet fields.
    //

    //  remember, we stripped the inbound header, so we only account for A and C fields
    /*NDIS_SET_PACKET_HEADER_SIZE(
                (PNDIS_PACKET) pRecBuf->packet,
                USB_CONTROL_FIELD_SIZE + USB_ADDRESS_FIELD_SIZE
                );*/

    //
    // Set the packet status to SUCCESS
    //
    NDIS_SET_PACKET_STATUS((PNDIS_PACKET) pRecBuf->packet, NDIS_STATUS_SUCCESS);     //for debug
    //
    // Indicate the packet to NDIS.
    //

    NdisMIndicateReceivePacket(
                Device->hNdisAdapter,
                &((PNDIS_PACKET) pRecBuf->packet),
                1
                );


    DEBUGMSG(DBG_FUNC, ("-DeliverBuffer\n"));
    return status;
}

⌨️ 快捷键说明

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