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