firda.c
来自「S3C24A0的完整BSP包,对开发此芯片的开发者很有用.」· C语言 代码 · 共 2,000 行 · 第 1/5 页
C
2,000 行
* Tell NDIS about the range of IO space that we'll be using.
*/
retStat = NdisMRegisterIoPortRange( (PVOID)thisDev->mappedPortRange,
NdisAdapterHandle,
thisDev->portInfo.ioBase,
20* 4);
if (retStat != NDIS_STATUS_SUCCESS){
DBGERR((TEXT("NdisMRegisterIoPortRange failed")));
result = NDIS_STATUS_FAILURE;
goto _initDone;
}
#endif
/*
* Record the NDIS wrapper's handle for this adapter, which we use
* when we call up to the wrapper.
* (This miniport's adapter handle is just thisDev, the pointer to the device object.).
*/
DEBUGFIR(DBGIRDA, (TEXT("NDIS handle: %xh <-> IRDA handle: ox%x\r\n"), (UINT)NdisAdapterHandle, (UINT)thisDev));
thisDev->ndisAdapterHandle = NdisAdapterHandle;
pIrdaGloabls->bFIREnabled = FALSE;
pIrdaGloabls->bUseDMA = FALSE;
/*
* Do special FIR module setup
*/
if (!IR24A0_Setup(thisDev)){
DEBUGMSG(DBGIRDA, (TEXT("IR24A0_Setup failed\r\n")));
result = NDIS_STATUS_FAILURE;
goto _initDone;
}
//Get SysIntr Ajay
#if 0
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &IrqIR, sizeof(DWORD), &dwSysIntrIR, sizeof(DWORD), NULL))
{
// invalid SDIO SYSINTR value!
RETAILMSG(1, (TEXT("invalid IRQ_FIR value!\n")));
dwSysIntrIR = SYSINTR_UNDEFINED;
result = FALSE;
goto _initDone;
}
RETAILMSG(1, (TEXT("fir irg %d MAPPED to SysIntr %d!\n"),IrqIR,dwSysIntrIR));
#endif
/*
* Register an interrupt with NDIS.
*/
DEBUGMSG(DBGIRDA, (TEXT("Calling NdisMRegisterInterrupt with SYSINTR_FIR value - %d\r\n"), dwSysIntrIR));
retStat = NdisMRegisterInterrupt( (PNDIS_MINIPORT_INTERRUPT)&thisDev->interruptObj,
NdisAdapterHandle,
dwSysIntrIR,//dwSysIntrIR-dwSysIntrFirmware,//(SYSINTR_IR - SYSINTR_FIRMWARE), // thisDev->portInfo.irq,
dwSysIntrIR,//dwSysIntrIR-dwSysIntrFirmware,//(SYSINTR_IR - SYSINTR_FIRMWARE), // thisDev->portInfo.irq,
TRUE, // want ISR
TRUE, // MUST share interrupts
NdisInterruptLevelSensitive
);
if (retStat != NDIS_STATUS_SUCCESS){
DEBUGMSG(DBGIRDA, (TEXT("NdisMRegisterInterrupt Returned - %s\r\n"), DBG_NDIS_RESULT_STR(retStat)));
DEBUGMSG(DBGIRDA, (TEXT("NdisMRegisterInterrupt failed\r\n")));
result = NDIS_STATUS_FAILURE;
goto _initDone;
}
if (!DoOpen(thisDev)){
DBGERR((TEXT("DoOpen failed")));
result = NDIS_STATUS_FAILURE;
goto _initDone;
}
_initDone:
if (result == NDIS_STATUS_SUCCESS){
/*
* Add this device object to the beginning of our global list.
*/
thisDev->next = firstIrDADevice;
firstIrDADevice = thisDev;
// For WinCE, we release the resources and they will be reclaimed,
// when OID_IRDA_REACQUIRE_HW_RESOURCES msg is recvd.
thisDev->resourcesReleased=TRUE;
CloseCOM(thisDev);
NdisReleaseSpinLock(&thisDev->Lock);
DEBUGMSG(DBGIRDA, (TEXT("MiniportInitialize succeeded\r\n")));
}
else {
if (thisDev){
FreeDevice(thisDev);
}
DEBUGMSG(DBGIRDA, (TEXT("MiniportInitialize failed\r\n")));
}
return result;
}
/*
*************************************************************************
* QueueReceivePacket
*************************************************************************
*
*
*
*
*/
VOID QueueReceivePacket(IrDevice *thisDev, PUCHAR data, UINT dataLen, BOOLEAN IsFIR)
{
rcvBuffer *rcvBuf = NULL;
PLIST_ENTRY ListEntry;
/*
* Note: We cannot use a spinlock to protect the rcv buffer structures
* in an ISR. This is ok, since we used a sync-with-isr function
* the the deferred callback routine to access the rcv buffers.
*/
// LOG(TEXT("==> QueueReceivePacket, len: "), dataLen);
// DBGOUT((TEXT("==> QueueReceivePacket(0x%x, 0x%lx, 0x%x)"),
// (UINT) thisDev, data, dataLen));
if (IsListEmpty(&thisDev->rcvBufFree))
{
ListEntry = NULL;
}
else
{
ListEntry = MyRemoveHeadList(&thisDev->rcvBufFree);
}
if (ListEntry)
{
// DBGOUT((TEXT("==> QueueReceivePacket: Dqueued List Entry (0x%x )"), (UINT) ListEntry));
rcvBuf = CONTAINING_RECORD(ListEntry,
rcvBuffer,
listEntry);
if (IsFIR)
{
LOG_Data(thisDev, data);
}
}
if (rcvBuf){
// DBGOUT((TEXT("==> QueueReceivePacket: rcvBuf found (0x%x )"), (UINT) rcvBuf));
rcvBuf->dataBuf = data;
VerifyNdisPacket(rcvBuf->packet, 0);
rcvBuf->state = STATE_FULL;
rcvBuf->dataLen = dataLen;
rcvBuf->isDmaBuf = IsFIR;
InsertTailList(&thisDev->rcvBufFull, ListEntry);
}
// LOG(TEXT("<== QueueReceivePacket"), 1);
// DBGOUT((TEXT("<== QueueReceivePacket")));
}
/*
*************************************************************************
* MiniportISR
*************************************************************************
*
*
* This is the miniport's interrupt service routine (ISR).
*
*
*/
VOID MiniportISR(PBOOLEAN InterruptRecognized,
PBOOLEAN QueueMiniportHandleInterrupt,
NDIS_HANDLE MiniportAdapterContext)
{
IrDevice *thisDev = CONTEXT_TO_DEV(MiniportAdapterContext);
// DEBUGFIR(1,(_T("MiniportISR Called\r\n")));
NdisAcquireSpinLock(&thisDev->Lock);
if (thisDev->currentSpeed > MAX_SIR_SPEED){
S24A0_FIR_ISR(thisDev, InterruptRecognized,
QueueMiniportHandleInterrupt);
} else {
COM_ISR(thisDev, InterruptRecognized,
QueueMiniportHandleInterrupt);
}
// InterruptDisable (SYSINTR_FIR);
#if 0
if (thisDev->resourcesReleased){
NdisReleaseSpinLock(&thisDev->Lock);
DBGOUT((TEXT("<== MiniportHandleInterrupt, blow off, no resources!")));
return;
}
// Intr_DMA_Done(thisDev, InterruptRecognized, QueueMiniportHandleInterrupt);
#if 0
if (thisDev->DmaInUse){ // Rx and Tx r handled by the same function
Intr_DMA_Done(thisDev, InterruptRecognized, QueueMiniportHandleInterrupt);
}
else {
Intr_Int_Done(thisDev, InterruptRecognized, QueueMiniportHandleInterrupt);
}
#endif
// Intr_DMA_Done(thisDev, InterruptRecognized, QueueMiniportHandleInterrupt);
if (thisDev->writePending) {
FIR_SendComplete(thisDev);
thisDev->AdapterState = ADAPTER_NONE;
/*
* Any more Tx packets?
*/
if (!IsListEmpty(&thisDev->SendQueue)) {
/* Kick off another Tx. */
DBGISR((TEXT("More packets in the Q Calling FIR_Send (0x%x)"), thisDev));
FIR_Send(thisDev);
} else {
thisDev->IntMask = 0x04;
DBGISR((TEXT("No More packets in the Q Calling SetupRecv (0x%x)"), thisDev));
FirSetupIntRecv(thisDev);
/*
* If we just sent the last frame to be sent at the old speed,
* set the hardware to the new speed.
* From OLD sytle!
*/
#if 0
if (thisDev->setSpeedAfterCurrentSendPacket) {
thisDev->setSpeedAfterCurrentSendPacket = FALSE;
SetSpeed(thisDev);
}
#endif
}
} else {
DBGISR((TEXT("Recvd PAcket .. Handling..... (0x%x)"), thisDev));
FIR_HandleRxFrame(thisDev);
DeliverFullBuffers(thisDev);
}
#endif
// InterruptDone(SYSINTR_FIR);
NdisReleaseSpinLock(&thisDev->Lock);
// DEBUGFIR(1,(_T("MiniportISR Return\r\n")));
// DEBUGMSG(DBGIRDA, (TEXT("<== MiniportISR [int recognized = %s, dpc = %s"),
// *InterruptRecognized ? TEXT("TRUE") : TEXT("FALSE"),
// *QueueMiniportHandleInterrupt ? TEXT("TRUE") : TEXT("FALSE")));
}
/*
*************************************************************************
* MiniportReconfigure
*************************************************************************
*
*
* Reconfigures the network interface card to new parameters available
* in the NDIS library configuration functions.
*
*
*/
NDIS_STATUS MiniportReconfigure ( OUT PNDIS_STATUS OpenErrorStatus,
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_HANDLE WrapperConfigurationContext
)
{
IrDevice *thisDev = CONTEXT_TO_DEV(MiniportAdapterContext);
NDIS_STATUS result;
DBGOUT((TEXT("MiniportReconfigure(0x%x)"), (UINT)MiniportAdapterContext));
MiniportHalt(MiniportAdapterContext);
if (Configure(thisDev, WrapperConfigurationContext)){
result = NDIS_STATUS_SUCCESS;
}
else {
result = NDIS_STATUS_FAILURE;
}
DBGOUT((TEXT("MiniportReconfigure")));
*OpenErrorStatus = result;
return result;
}
/*
*************************************************************************
* MiniportReset
*************************************************************************
*
*
* MiniportReset issues a hardware reset to the network interface card.
* The miniport driver also resets its software state.
*
*
*/
// NOTE: Arguments are reversed from as documented in April '96 MSDN!
NDIS_STATUS MiniportReset(PBOOLEAN AddressingReset, NDIS_HANDLE MiniportAdapterContext)
{
IrDevice *dev, *thisDev = CONTEXT_TO_DEV(MiniportAdapterContext);
NDIS_STATUS result = NDIS_STATUS_SUCCESS;
DEBUGMSG(DBGIRDA, (TEXT("MiniportReset(0x%x)"), (UINT)MiniportAdapterContext));
/*
* Verify that the context is not bogus.
* I've seen bad contexts getting passed in when the system gets corrupted.
*/
for (dev = firstIrDADevice; dev && (dev != thisDev); dev = dev->next){}
if (!dev){
DEBUGMSG(DBGIRDA, (TEXT("Bad context in MiniportReset\r\n")));
return NDIS_STATUS_FAILURE;
}
NdisAcquireSpinLock(&thisDev->Lock);
DoClose(thisDev);
CloseDevice(thisDev);
OpenDevice(thisDev);
DoOpen(thisDev);
NdisReleaseSpinLock(&thisDev->Lock);
*AddressingReset = TRUE;
DEBUGMSG(DBGIRDA, (TEXT("MiniportReset done.\r\n")));
return result;
}
//
// NOTE: Under WinCE, only MiniportSend will ever be called. On NT and 98,
// MiniportSend is the serial IR handler for SendPacketsHandler.
// SendCommPacket is the SIR handler and MiniportSend handles both
// the SIR and FIR routing.
//
NDIS_STATUS
SendCommPacket(
IN IrDevice *thisDev,
IN PNDIS_PACKET Packet
)
{
NDIS_STATUS result;
DBGOUT((TEXT("==>SendCommPacket(thisDev=0x%x)"), (UINT)thisDev));
DEBUGMSG(DBG_TRACE_TX, (TEXT("+SendCommPacket(pkt = 0x%x)\r\n"), Packet));
/*
* If we have temporarily lost access to the hardware, don't queue up any sends.
* return success until we regain access to the hw.
*/
if (thisDev->resourcesReleased){
return NDIS_STATUS_SUCCESS;
}
DBGPKT((TEXT("Queueing send packet 0x%x."), (UINT)Packet));
//
// Use MiniportReserved as a LIST_ENTRY. First check so no one
// ever changes the size of these the wrong way.
//
ASSERT(sizeof(Packet->MiniportReserved)>=sizeof(LIST_ENTRY));
InsertTailList(&thisDev->SendQueue, (PLIST_ENTRY)Packet->MiniportReserved);
/*
* Try to send the first queued send packet.
*/
if (IsCommReadyForTransmit(thisDev)){
BOOLEAN firstBufIsPending;
firstBufIsPending = (BOOLEAN)(Packet != HEAD_SEND_PACKET(thisDev));
result = PortReadyForWrite(thisDev, firstBufIsPending);
DEBUGMSG(DBG_TRACE_TX, (TEXT("PortReadyForWrite returned 0x%x\r\n"),
result));
}
else {
DEBUGMSG(DBG_TRACE_TX, (TEXT("SendCommPacket: NDIS_STATUS_PENDING\r\n")));
result = NDIS_STATUS_PENDING;
}
DBGOUT((TEXT("<==SendCommPacket [%s]"), DBG_NDIS_RESULT_STR(result)));
return result;
}
/*
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?