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 + -
显示快捷键?