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

📄 nsc.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
📖 第 1 页 / 共 5 页
字号:
		}
#endif

        rcvBuf->dataBuf = data;

        VerifyNdisPacket(rcvBuf->packet, 0);
        rcvBuf->state = STATE_FULL;
        rcvBuf->dataLen = dataLen;

        if (!IsFIR)
        {
            rcvBuf->isDmaBuf = FALSE;
            InsertTailList(&thisDev->rcvBufFull,
                           ListEntry);
        }
        else
        {
            rcvBuf->isDmaBuf = TRUE;
            LOG_InsertTailList(thisDev, &thisDev->rcvBufFull, rcvBuf);
            NDISSynchronizedInsertTailList(&thisDev->rcvBufFull,
                                           ListEntry,
                                           &thisDev->interruptObj);
        }
    }
    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); 

	*InterruptRecognized          = FALSE;
	*QueueMiniportHandleInterrupt = FALSE;

	{
		UINT	val;
		//IrDA int req?
		val = READ_REGISTER_USHORT(pNIRR);
		if(val & CC_INTC_NIRR_IRDAR){
			// It's our Iinterrupt
			;
		}
		else{
			DEBUGMSG(1, (TEXT("MiniportISR: SPURIOUS INT!!!!!!!!!!!!!!!!!\r\n")));
			*InterruptRecognized 		  = FALSE;
			*QueueMiniportHandleInterrupt = FALSE;
		}
	}

    if (!thisDev->resourcesReleased){
        /*
         *  Service the interrupt.
         */
        if (thisDev->currentSpeed > MAX_SIR_SPEED){

            NSC_FIR_ISR(thisDev, InterruptRecognized,
                        QueueMiniportHandleInterrupt);
        }
        else {

            COM_ISR(thisDev, InterruptRecognized,
                    QueueMiniportHandleInterrupt);
        }

#ifdef UNDER_CE		
    	if (*InterruptRecognized == TRUE && *QueueMiniportHandleInterrupt == TRUE)
    	{

        	MiniportHandleInterrupt(MiniportAdapterContext);
        	*QueueMiniportHandleInterrupt = FALSE;

        	// NDIS normally re-enables ints for me after the DPC, but does
        	// NOT if a DPC is not required.


			SetCOMInterrupts(thisDev, TRUE);
//			WRITE_REGISTER_UCHAR(pIMSTCR, READ_REGISTER_UCHAR(pIMSTCR) | CC_FIR_IMSTCR_IEN);

 	   }	// end move
#endif
    }
	else{
		/* clear interrupt */
		UCHAR iir;

		iir = READ_REGISTER_UCHAR(pIrIIR);
		if(iir & 0x01){
			// interrupt none
				;
		}else{
			switch(iir & 0x0e){
				case SERIAL_IIR_MS:
					// Modem Status
					READ_REGISTER_UCHAR(pIrMSR);
					break;
				case SERIAL_IIR_THRE:
					// Transmitter Holding Register Empty
					break;
				case SERIAL_IIR_RDA:
					// Receive Data Available
					READ_REGISTER_UCHAR(pIrRBR);
					break;
				case SERIAL_IIR_RLS:
					// Receiver Line Status
					READ_REGISTER_UCHAR(pIrLSR);
				case SERIAL_IIR_CTI:
					// Character Timer-out Indication
					READ_REGISTER_UCHAR(pIrRBR);
				default:
					break;
			}
		}
	}
	*InterruptRecognized = TRUE;
	*QueueMiniportHandleInterrupt = 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;

    DBGOUT((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 = firstIrDevice; dev && (dev != thisDev); dev = dev->next){}
    if (!dev){
        DBGERR((TEXT("Bad context in MiniportReset")));
        return NDIS_STATUS_FAILURE;
    }

    DoClose(thisDev);
    CloseDevice(thisDev);

    /*** change start ***/
    if(OpenDevice(thisDev) && DoOpen(thisDev)){
    	*AddressingReset = TRUE;
    	result = NDIS_STATUS_SUCCESS;
    }else{
    	*AddressingReset = FALSE;
    	result = NDIS_STATUS_HARD_ERRORS;
    }

    /*** change end   ***/

    DBGOUT((TEXT("MiniportReset done.")));
    return result;
}

#ifdef UNDER_CE

//
// 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.
     *  Just pretend everything is going smoothly 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));

    NdisInterlockedInsertTailList(&thisDev->SendQueue,
                                  (PLIST_ENTRY)Packet->MiniportReserved,
                                  &thisDev->QueueLock);

    /*
     *  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;
}

/*
 *************************************************************************
 *  MiniportSend
 *************************************************************************
 *
 *
 *  Transmits a packet through the network interface card onto the medium.
 *
 *
 *
 */
NDIS_STATUS MiniportSend(
                        IN NDIS_HANDLE MiniportAdapterContext,
                        IN PNDIS_PACKET Packet,
                        IN UINT Flags
                        )
{
    NDIS_STATUS stat;
    BOOLEAN TxWasActive, DmaPend;

    IrDevice *thisDev = CONTEXT_TO_DEV(MiniportAdapterContext);

    LOG(TEXT("==> MiniportSend"), 0);
    DBGOUT((TEXT("==> MiniportSend(0x%x, pakcet = 0x%x)"), 
            (UINT)MiniportAdapterContext, Packet));

    DEBUGMSG(DBG_TX | DBG_TRACE_TX, 
        (TEXT("+MiniportSend(pkt = 0x%x)\r\n"), Packet));

    //
    //  If we have temporarily lost access to the hardware, don't queue up any sends.
    //  Just pretend everything is going smoothly until we regain access to the hw.
    //
    if (thisDev->resourcesReleased){
        ASSERT(FALSE);

#ifdef OUTMSG
		RETAILMSG(1, (TEXT("ERROR resourcesReleased in MiniportSend\r\n")));
#endif
        return (NDIS_STATUS_FAILURE);
    }

    IRFIR_LOG_NDIS_PACKET(LOG_TXFRAME, Packet);

    if (thisDev->currentSpeed > MAX_SIR_SPEED)
    {
        DEBUGMSG(DBG_TRACE_TX, (TEXT("MSend => MIR | FIR\r\n")));

        NdisAcquireSpinLock(&thisDev->QueueLock);
        TxWasActive = (thisDev->AdapterState==ADAPTER_TX);
        thisDev->AdapterState = ADAPTER_TX;
        NDIS_SET_PACKET_STATUS(Packet, NDIS_STATUS_PENDING);
        InsertTailList(&thisDev->SendQueue,
            (PLIST_ENTRY)Packet->MiniportReserved);
        NdisReleaseSpinLock(&thisDev->QueueLock);

		if(READ_REGISTER_UCHAR(pISIRR) & CC_FIR_ISIRR_SIRMOD){
			DmaPend = FALSE;
		}else{
			WRITE_REGISTER_UCHAR(pIMSTCR, (READ_REGISTER_UCHAR(pIMSTCR) & CC_FIR_IMSTCR_RST_BANK)|CC_FIR_IMSTCR_BANK0 );
			DmaPend = (BOOLEAN)(READ_REGISTER_UCHAR(pIRSR) & CC_FIR_IRSR_RFEM);
		}
		if (!TxWasActive)
        {
            DEBUGMSG(DBG_TRACE_TX, (TEXT("MSend => TX idle, do work...\r\n")));
            //
            // Complete the Receive DMA before starting the next
            // set of transmits.
            //

            NdisMCompleteDmaTransfer(&stat, thisDev->DmaHandle,
                                     thisDev->rcvDmaBuffer, 
                                     thisDev->rcvDmaOffset,
                                     thisDev->rcvDmaSize, FALSE);

            DEBUGMSG(DBG_TRACE_TX, (TEXT("MSend: CompleteDma returned 0x%x\r\n"),
                                    stat));
    
            if (!RegStats.RxWindow) {
                LOG(TEXT("SendPacketsHandler - RxWindow has zero value"), 0);
                DBGOUT((TEXT("SendPacketsHandler - RxWindow has zero value")));
            }
    
            if (RegStats.RxDPC_Window > 1) {
                RegStats.RxDPC_G1_Count++;
            }
    
            RegStats.RxWindowMax = MAX(RegStats.RxWindowMax, RegStats.RxWindow);
            RegStats.RxWindow = 0;
            RegStats.RxDPC_WindowMax = MAX(RegStats.RxDPC_WindowMax, RegStats.RxDPC_Window);
            RegStats.RxDPC_Window = 0;
    
            //
            // Use DMA swap bit to switch to DMA to Transmit.
            //

            //
            // Switch on the DMA interrupt to decide when
            // transmission is complete.
            //

            thisDev->IntMask = 0x14;
            SetCOMInterrupts(thisDev, TRUE);
            //
            // Kick off the first transmit.
            //


            FIR_MegaSend(thisDev);
        }
        else
        {
            DEBUGMSG(DBG_TRACE_TX, (TEXT("MSend: TX active, queue packet\r\n")));
        }
        stat = NDIS_STATUS_PENDING;

⌨️ 快捷键说明

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