firda.c

来自「S3C24A0的完整BSP包,对开发此芯片的开发者很有用.」· C语言 代码 · 共 2,000 行 · 第 1/5 页

C
2,000
字号
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//


#include "firda.h"
//#include "s24a0.h"
#include "nkintr.h"
//#include "oalintr.h"
#include "drv_glob.h"
#include "s3c24a0_intr.h"
#include "s3c24a0_irda.h"
#include "s3c24a0_ioport.h"
#include "s3c24a0_clkpwr.h"
#include "s3c24a0_dma.h"
#include "s3c24a0_uart.h"

/* This fuction sets up the device for Recv */
void SetupRecv(IrDevice *thisDev);

volatile IRDA_GLOBALS *pIrdaGloabls=&((DRIVER_GLOBALS *)DRIVER_GLOBALS_PHYSICAL_MEMORY_START)->irda;

//
// Debug Counters
//
DebugCounters RegStats = {0,0,0,0,0,0,0,0,0};

#ifdef RECEIVE_PACKET_LOGGING

typedef struct {
    UCHAR Data[12];
} DATA_BITS;


typedef struct {
    USHORT Tag;
    USHORT Line;
    union {
        struct {
            PNDIS_PACKET    Packet;
            PVOID           DmaBuffer;
            ULONG           Length;
        } Packet;
        struct {
            PLIST_ENTRY     Head;
            PLIST_ENTRY     Entry;
        } List;
        struct {
            PVOID           Start;
            ULONG           Offset;
            ULONG           Length;
        } Dma;
        DATA_BITS Data;
    };
} RCV_LOG;

#define CHAIN_PACKET_TAG 'CP'
#define UNCHAIN_PACKET_TAG 'UP'
#define ADD_HEAD_LIST_TAG 'HA'
#define ADD_TAIL_LIST_TAG 'TA'
#define REMOVE_HEAD_LIST_TAG 'HR'
#define REMOVE_ENTRY_TAG 'ER'
#define DMA_TAG  'MD'
#define DATA_TAG 'AD'
#define DATA2_TAG '2D'

#define NUM_RCV_LOG 256

ULONG   RcvLogIndex = 0;
RCV_LOG RcvLog[NUM_RCV_LOG];

BOOLEAN SyncGetRcvLogEntry(PVOID Context)
{
    *(ULONG*)Context = RcvLogIndex++;
    RcvLogIndex &= NUM_RCV_LOG-1;
    return TRUE;
}

ULONG __inline GetRcvLogEntry(IrDevice *thisDev)
{
    ULONG Entry;

    NdisAcquireSpinLock(&thisDev->Lock);
    SyncGetRcvLogEntry(&Entry);
    NdisReleaseSpinLock(&thisDev->Lock);
    return Entry;
}



#define LOG_InsertHeadList(d, h, e)         \
{                                           \
    ULONG i = GetRcvLogEntry(d);            \
    RcvLog[i].Tag = ADD_HEAD_LIST_TAG;      \
    RcvLog[i].Line = __LINE__;              \
    RcvLog[i].List.Head = (h);                   \
    RcvLog[i].List.Entry = (PLIST_ENTRY)(e);                  \
}

#define LOG_InsertTailList(d, h, e)         \
{                                           \
    ULONG i = GetRcvLogEntry(d);            \
    RcvLog[i].Tag = ADD_TAIL_LIST_TAG;      \
    RcvLog[i].Line = __LINE__;              \
    RcvLog[i].List.Head = (h);              \
    RcvLog[i].List.Entry = (PLIST_ENTRY)(e);             \
}

#define LOG_RemoveHeadList(d, h, e)         \
{                                           \
    ULONG i = GetRcvLogEntry(d);            \
    RcvLog[i].Tag = REMOVE_HEAD_LIST_TAG;      \
    RcvLog[i].Line = __LINE__;              \
    RcvLog[i].List.Head = (h);              \
    RcvLog[i].List.Entry = (PLIST_ENTRY)(e);             \
}

#define LOG_RemoveEntryList(d, e)           \
{                                           \
    ULONG i = GetRcvLogEntry(d);            \
    RcvLog[i].Tag = REMOVE_ENTRY_TAG;       \
    RcvLog[i].Line = __LINE__;              \
    RcvLog[i].List.Head = NULL;             \
    RcvLog[i].List.Entry = (PLIST_ENTRY)(e);             \
}

#define LOG_PacketChain(d, p)                                   \
{                                                               \
    PNDIS_BUFFER NdisBuffer;                                    \
    PVOID Address;                                              \
    ULONG Len;                                                  \
    ULONG i = GetRcvLogEntry(d);                                \
    RcvLog[i].Tag = CHAIN_PACKET_TAG;                           \
    RcvLog[i].Line = __LINE__;                                  \
    NdisQueryPacket((p), NULL, NULL, &NdisBuffer, NULL);        \
    NdisQueryBuffer(NdisBuffer, &Address, &Len);                \
    RcvLog[i].Packet.Packet = (p);                              \
    RcvLog[i].Packet.DmaBuffer = Address;                       \
    RcvLog[i].Packet.Length = Len;                              \
}

#define LOG_PacketUnchain(d, p)                                 \
{                                                               \
    PNDIS_BUFFER NdisBuffer;                                    \
    PVOID Address;                                              \
    ULONG Len;                                                  \
    ULONG i = GetRcvLogEntry(d);                                \
    RcvLog[i].Tag = UNCHAIN_PACKET_TAG;                         \
    RcvLog[i].Line = __LINE__;                                  \
    NdisQueryPacket((p), NULL, NULL, &NdisBuffer, NULL);        \
    NdisQueryBuffer(NdisBuffer, &Address, &Len);                \
    RcvLog[i].Packet.Packet = (p);                              \
    RcvLog[i].Packet.DmaBuffer = Address;                       \
    RcvLog[i].Packet.Length = Len;                              \
}

#define LOG_Dma(d)                                              \
{                                                               \
    ULONG i = GetRcvLogEntry(d);                                \
    RcvLog[i].Tag = DMA_TAG;                                    \
    RcvLog[i].Line = __LINE__;                                  \
    RcvLog[i].Dma.Start = (d)->rcvDmaBuffer;                    \
    RcvLog[i].Dma.Offset = (d)->rcvDmaOffset;                   \
    RcvLog[i].Dma.Length = (d)->rcvDmaSize;                     \
}

#define LOG_Data(d,s)                                           \
{                                                               \
    ULONG i = GetRcvLogEntry(d);                                \
    RcvLog[i].Tag = DATA_TAG;                                   \
    RcvLog[i].Line = ((USHORT)(s))&0xffff;                      \
    RcvLog[i].Data = *(DATA_BITS*)(s);                          \
}

#define LOG_Data2(d,s)                                           \
{                                                               \
    ULONG i = GetRcvLogEntry(d);                                \
    RcvLog[i].Tag = DATA2_TAG;                                   \
    RcvLog[i].Line = ((USHORT)(s))&0xffff;                      \
    RcvLog[i].Data = *(DATA_BITS*)(s);                          \
}

void DumpNdisPacket(PNDIS_PACKET Packet, UINT Line)
{
    UINT PhysBufCnt, BufCnt, TotLen, Len;
    PNDIS_BUFFER NdisBuffer;
    PVOID Address;

    DbgPrint("Badly formed NDIS packet at line %d\n", Line);

    NdisQueryPacket(Packet, &PhysBufCnt, &BufCnt, &NdisBuffer, &TotLen);
    DbgPrint("Packet:%08X  PhysBufCnt:%d BufCnt:%d TotLen:%d\n",
             Packet, PhysBufCnt, BufCnt, TotLen);
    while (NdisBuffer)
    {
        NdisQueryBuffer(NdisBuffer, &Address, &Len);
        DbgPrint("   Buffer:%08X Address:%08X Length:%d\n",
                 NdisBuffer, Address, Len);
        NdisGetNextBuffer(NdisBuffer, &NdisBuffer);
    }
    DbgBreakPoint();
}

#define VerifyNdisPacket(p, b) \
{                                                       \
    UINT BufCnt;                                        \
                                                        \
    NdisQueryPacket((p), NULL, &BufCnt, NULL, NULL);    \
    if (BufCnt>(b))                                     \
    {                                                   \
        DumpNdisPacket((p), __LINE__);                  \
    }                                                   \
}
#else
#define VerifyNdisPacket(p,b)
#define LOG_InsertHeadList(d, h, e)
#define LOG_InsertTailList(d, h, e)
#define LOG_RemoveHeadList(d, h, e)
#define LOG_RemoveEntryList(d, e)
#define LOG_PacketChain(d, p)
#define LOG_PacketUnchain(d, p)
#define LOG_Dma(d)
#define LOG_Data(d,s)
#define LOG_Data2(d,s)
#endif


//DWORD dwSysIntrIR=0; 
DWORD dwSysIntrIR=IRQ_FIR;
DWORD IrqIR =IRQ_FIR;

// Registers of various components being used in the IRDA module
//
volatile S3C24A0_IRDA_REG	*g_pIRDAregs	= NULL;		// IRDA registers 
volatile S3C24A0_DMA_REG	*g_pDMA0regs	= NULL;		// DMA0 registers IRDA
volatile S3C24A0_DMA_REG	*g_pDMA1regs	= NULL;		// DMA0 registers IRDA
volatile S3C24A0_IOPORT_REG	*g_pIOPregs	= NULL;		// IOP registers 
volatile S3C24A0_INTR_REG 	*g_pINTregs 	= NULL;		// Interrupt controller registers
volatile S3C24A0_CLKPWR_REG	*g_pClkPwrRegs 	= NULL;		// Interrupt controller registers
volatile S3C24A0_UART_REG	*g_pComm1Reg = NULL;    // uart 1 register

#define INT_BASE		0xB0300000 // 0x40200000 -> 0x90300000
#define IOP_BASE        0xB1300000 // 0x44800000
#define CLKPWR_BASE    0xB0200000 // 0x40000000
#define DMA0_BASE    0xB0400000 // 0x40400000
#define DMA1_BASE    0xB0500000 // 0x40500000
#define UART1_BASE      0xB0F04000 // 0x44404000

// DMA Buffer 
//
PVOID g_pvDmaVirtualBase;

/*
 *  We keep a linked list of device objects
 */
IrDevice *firstIrDADevice = NULL;

#ifdef UNDER_CE
//
// Debugging information.
//

#ifdef DEBUG

DBGPARAM dpCurSettings =
{
        TEXT("Irda"),
        {
            TEXT("Init"),       TEXT("SirMode"),
            TEXT("FirMode"),    TEXT("Tx"),
            TEXT("Rx"),         TEXT("TxTrace"),
            TEXT("Packet"),     TEXT("Isr"),
            TEXT("Dma"),        TEXT("Undefined"),
            TEXT("Stat"),       TEXT("Log"),
            TEXT("Buffer"),     TEXT("Msg"),
            TEXT("Warn"),       TEXT("Error")
        },
        0x00008001
};

#endif // DEBUG

/* This fuction sets up the device for Recv */
void SetupRecv(IrDevice *thisDev);

BOOL AllocReg();	
VOID FreeReg();	

BOOL WINAPI
DllEntry(
    HANDLE hInstDll,
    DWORD  Op,
    LPVOID lpvReserved
    )
{
    ULONG nTmpVal;

    switch (Op)
    {
        case DLL_PROCESS_ATTACH:

            DEBUGREGISTER((HMODULE)hInstDll);
            IRFIR_LOG_INIT();
            RETAILMSG(DBGIRDA, (TEXT("FIR DllEntry: DLL Process Attach.\r\n")));

            //
            // Windows CE. Allocate contiguous memory from drivers globals. See
            // externs.h.
            // Need to get virtual pointer to our DMA physical.
            //
        
            // Check to make sure that our buffer requirements have not changed.
            //ASSERT((NUM_RCV_BUFS * RCV_BUFFER_SIZE) == 33024);
            //ASSERT((RCV_BUFFER_SIZE + MAX_IRDA_DATA_SIZE * 8) == 35264);
            //ASSERT(RCV_DMA_SIZE == 18504);

            g_pvDmaVirtualBase = VirtualAlloc(
                0, S24A0IRDA_DMA_BUFFER_LEN, 
                MEM_RESERVE, PAGE_NOACCESS);
        
            if (g_pvDmaVirtualBase == NULL)
            {
            	DBGERR((TEXT("g_pvDmaVirtualBase is NULL :(((( - exiting\r\n")));
                return (FALSE);
            }
        
            nTmpVal = VirtualCopy(
                g_pvDmaVirtualBase,
                (LPVOID)(S24A0IRDA_DMA_BUFFER_BASE),	
                S24A0IRDA_DMA_BUFFER_LEN,
                PAGE_READWRITE | PAGE_NOCACHE);
			
 	     
		 
            if (nTmpVal != TRUE)
            {
                DBGERR((TEXT("Mapping of g_pvDmaVirtualBase failed :((((( \r\n")));
                return (FALSE);
            }
			
            DEBUGFIR(DBGIRDA, (TEXT("Mapping of g_pvDmaVirtualBase done %x\r\n"), g_pvDmaVirtualBase));
			
            // Allocate the registers a chunk from memory
            //
            DEBUGFIR(DBGIRDA, (TEXT("Calling AllocReg\r\n")));            
	    if(AllocReg() != TRUE)
	    {
		return (FALSE);
	    }
        
	        DisableThreadLibraryCalls((HMODULE) hInstDll);
            break;

        case DLL_PROCESS_DETACH:

            RETAILMSG(DBGIRDA, (TEXT("Fir Dll Entry: DLL Process Detach.\r\n")));

            // Free our virtual address.
            if (g_pvDmaVirtualBase)
            {
                VirtualFree(
                    g_pvDmaVirtualBase, 
                    0, 
                    MEM_RELEASE);

                g_pvDmaVirtualBase = NULL;
            }
            
            // Free the resources taken up
            //
            FreeReg();
            break;

        default:
            break;
    }

    return (TRUE);
}

#endif // UNDER_CE

/*
 *************************************************************************
 *  MiniportCheckForHang
 *************************************************************************
 *
 *  Reports the state of the network interface card.
 *
 */
BOOLEAN MiniportCheckForHang(NDIS_HANDLE MiniportAdapterContext)
{
    IrDevice *thisDev = CONTEXT_TO_DEV(MiniportAdapterContext);

⌨️ 快捷键说明

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