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

📄 nsc.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
📖 第 1 页 / 共 5 页
字号:
     *  but I've seen devices get extra resources.
     *  So give the NdisMQueryAdapterResources call room for 10 resources.
     */
    #define RESOURCE_LIST_BUF_SIZE (sizeof(NDIS_RESOURCE_LIST) + (10*sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)))

    UCHAR buf[RESOURCE_LIST_BUF_SIZE];
    PNDIS_RESOURCE_LIST resList = (PNDIS_RESOURCE_LIST)buf;
    UINT bufSize = RESOURCE_LIST_BUF_SIZE;

	DBGOUT((TEXT("==>GetPnPResources")));

    NdisMQueryAdapterResources(&stat, WrapperConfigurationContext, resList, &bufSize);
    if (stat == NDIS_STATUS_SUCCESS){
        PCM_PARTIAL_RESOURCE_DESCRIPTOR resDesc;
        BOOLEAN     haveIRQ = FALSE,
                    haveIOAddr = FALSE,
                    haveDma = FALSE;
        UINT i;

        for (resDesc = resList->PartialDescriptors, i = 0;
             i < resList->Count;
             resDesc++, i++){

            switch (resDesc->Type){
                case CmResourceTypePort:
                    if (haveIOAddr){
                        /*
                         *  The *PNP0510 chip on the IBM ThinkPad 760EL
                         *  gets an extra IO range assigned to it.
                         *  So only pick up the first IO port range;
                         *  ignore this subsequent one.
                         */
                        DBGERR(("Ignoring extra PnP IO base %xh because already using %xh.",
                                  (UINT)resDesc->u.Port.Start.LowPart,
                                  (UINT)thisDev->portInfo.ioBase));
                    }
                    else {
                        thisDev->portInfo.ioBase = resDesc->u.Port.Start.LowPart;
                        haveIOAddr = TRUE;
                        DBGOUT(("Got UART IO addr: %xh.", thisDev->portInfo.ioBase));
                    }
                    break;

                case CmResourceTypeInterrupt:
                    if (haveIRQ){
                        DBGERR(("Ignoring second PnP IRQ %xh because already using %xh.",
                                (UINT)resDesc->u.Interrupt.Level, thisDev->portInfo.irq));
                    }
                    else {
                            thisDev->portInfo.irq = resDesc->u.Interrupt.Level;
                        haveIRQ = TRUE;
                        DBGOUT(("Got PnP IRQ: %d.", thisDev->portInfo.irq));
                    }
                    break;

                case CmResourceTypeDma:
                    if (haveDma){
                        DBGERR(("Ignoring second DMA address %d because already using %d.",
                                (UINT)resDesc->u.Dma.Channel, (UINT)thisDev->portInfo.DMAChannel));
                    }
                    else {
                        ASSERT(!(resDesc->u.Dma.Channel&0xffffff00));
                        thisDev->portInfo.DMAChannel = (UCHAR)resDesc->u.Dma.Channel;
                        haveDma = TRUE;
                        DBGOUT(("Got DMA channel: %d.", thisDev->portInfo.DMAChannel));
                    }
                    break;
            }
        }

        result = (haveIOAddr && haveIRQ && haveDma);
    }

	DBGOUT((TEXT("<==GetPnPResources")));
    return result;
}
#endif // !UNDER_CE


/*
 *************************************************************************
 *  Configure
 *************************************************************************
 *
 *  Read configurable parameters out of the system registry.
 *
 */
BOOLEAN Configure(
                 IrDevice *thisDev, 
                 NDIS_HANDLE WrapperConfigurationContext
                 )
{
    //
    // Status of Ndis calls.
    //
    NDIS_STATUS Status;

    //
    // The handle for reading from the registry.
    //
    NDIS_HANDLE ConfigHandle;

    //
    // TRUE if there is a configuration error.
    //
    BOOLEAN ConfigError = FALSE;

    //
    // A special value to log concerning the error.
    //
    ULONG ConfigErrorValue = 0;

#ifndef UNDER_CE
    ULONG SlotNumber;
#endif // !UNDER_CE


    DBGOUT((TEXT("Configure(0x%x)"), (UINT)thisDev));
    NdisOpenConfiguration(&Status, &ConfigHandle, WrapperConfigurationContext);
    if (Status != NDIS_STATUS_SUCCESS){
        DBGERR((TEXT("NdisOpenConfiguration failed in Configure()")));
        return FALSE;
    }

    NdisCloseConfiguration(ConfigHandle);

    DBGINIT((TEXT("NSC configure done: ConfigIO=0x%x UartIO=0x%x irq=%d DMA=%d"), 
        thisDev->portInfo.ConfigIoBaseAddr,thisDev->portInfo.ioBase,
        thisDev->portInfo.irq,thisDev->portInfo.DMAChannel));

	DBGOUT((TEXT("<==Configure")));
    return TRUE;
}


/*
 *************************************************************************
 *  MiniportInitialize
 *************************************************************************
 *
 *
 *  Initializes the network interface card.
 *
 *
 *
 */
NDIS_STATUS MiniportInitialize  (   PNDIS_STATUS OpenErrorStatus,
                                    PUINT SelectedMediumIndex,
                                    PNDIS_MEDIUM MediumArray,
                                    UINT MediumArraySize,
                                    NDIS_HANDLE NdisAdapterHandle,
                                    NDIS_HANDLE WrapperConfigurationContext
                                )
{
    UINT mediumIndex;
    IrDevice *thisDev = NULL;   
    NDIS_STATUS retStat, result = NDIS_STATUS_SUCCESS;

    DBGOUT((TEXT("MiniportInitialize()")));

    /*
     *  Search the passed-in array of supported media for the IrDA medium.
     */
    for (mediumIndex = 0; mediumIndex < MediumArraySize; mediumIndex++){
        if (MediumArray[mediumIndex] == NdisMediumIrda){
            break;
        }
    }
    if (mediumIndex < MediumArraySize){
        *SelectedMediumIndex = mediumIndex;
    }
    else {
        /*
         *  Didn't see the IrDA medium
         */
        DBGERR((TEXT("Didn't see the IRDA medium in MiniportInitialize")));
        result = NDIS_STATUS_UNSUPPORTED_MEDIA;
        goto _initDone;
    }

    /*
     *  Allocate a new device object to represent this connection.
     */
    thisDev = NewDevice();
    if (!thisDev){
        return NDIS_STATUS_NOT_ACCEPTED;
    }

#ifdef UNDER_CE
    // CE - calls NdisMInitializeTimer instead of NdisInitializeTimer. This
    //      requires the NdisAdapterHandle. Else the timer is initialized
    //      in InitDevice.
    NdisMInitializeTimer(&thisDev->TurnaroundTimer,
                        NdisAdapterHandle,
                        DelayedWrite,
                        thisDev);
#endif // UNDER_CE

    /*
     *  Allocate resources for this connection.
     */
    if (!OpenDevice(thisDev)){
        DBGERR((TEXT("OpenDevice failed")));
        result = NDIS_STATUS_FAILURE;
        goto _initDone;
    }


    /*
     *  Read the system registry to get parameters like COM port number, etc.
     */
    if (!Configure(thisDev, WrapperConfigurationContext)){
        result = NDIS_STATUS_FAILURE;
        goto _initDone;
    }

    /*
     *  This call will associate our adapter handle with the wrapper's
     *  adapter handle.  The wrapper will then always use our handle
     *  when calling us.  We use a pointer to the device object as the context.
     */
    NdisMSetAttributes  (   NdisAdapterHandle,
                            (NDIS_HANDLE)thisDev,
                            FALSE,
                            NdisInterfaceInternal  
                        );


    /*
     *  Tell NDIS about the range of IO space that we'll be using.
     */
    /* retStat = NdisMRegisterIoPortRange( (PVOID)thisDev->mappedPortRange,
                                        NdisAdapterHandle,
                                        thisDev->portInfo.ioBase,
                                        8);

    if (retStat != NDIS_STATUS_SUCCESS){
        DBGERR((TEXT("NdisMRegisterIoPortRange failed")));
        result = NDIS_STATUS_FAILURE;
        goto _initDone;
    }
    */


    /*
     *  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.).
     */
    DBGOUT((TEXT("NDIS handle: %xh <-> NSCIRDA handle: %xh"), 
        (UINT)NdisAdapterHandle, (UINT)thisDev));
    thisDev->ndisAdapterHandle = NdisAdapterHandle;


    /*
     *  Open COMM communication channel.
     *  This will let the dongle driver update its capabilities from their default values.
     */
    if (!DoOpen(thisDev)){
        DBGERR((TEXT("DoOpen failed")));
        result = NDIS_STATUS_FAILURE;
        goto _initDone;
    }


    /*
     *  Do special NSC setup
     *  (do this after comport resources, like read buf, have been allocated).
     */
    if (!NSC_Setup(thisDev)){
        DBGERR((TEXT("NSC_Setup failed")));
        result = NDIS_STATUS_FAILURE;
        goto _initDone;
    }


    /*
     *  Register an interrupt with NDIS.
     */
    retStat = NdisMRegisterInterrupt(   (PNDIS_MINIPORT_INTERRUPT)&thisDev->interruptObj,
                                        NdisAdapterHandle,
                                        dwSysIntrIR-dwSysIntrFirmware,//(SYSINTR_IR - SYSINTR_FIRMWARE),	// thisDev->portInfo.irq,
                                        dwSysIntrIR-dwSysIntrFirmware,//(SYSINTR_IR - SYSINTR_FIRMWARE),	// thisDev->portInfo.irq,
                                        TRUE,   // want ISR
                                        TRUE,   // MUST share interrupts
                                        NdisInterruptLevelSensitive	//99.04.21 NdisInterruptLatched
                                    );
    if (retStat != NDIS_STATUS_SUCCESS){
        DBGERR((TEXT("NdisMRegisterInterrupt 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 = firstIrDevice;
        firstIrDevice = thisDev;
#ifdef UNDER_CE
        // 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);
        // Still successful.
#else // UNDER_CE
        thisDev->resourcesReleased=FALSE;
#endif //!UNDER_CE
        DBGOUT((TEXT("MiniportInitialize succeeded")));
    }
    else {
        if (thisDev){
            FreeDevice(thisDev);
        }
        DBGERR((TEXT("MiniportInitialize failed")));
    }
    return result;

}



/*
 *************************************************************************
 * QueueReceivePacket
 *************************************************************************
 *
 *
 *
 *
 */
VOID QueueReceivePacket(IrDevice *thisDev, PUCHAR data, UINT dataLen, BOOLEAN IsFIR) /* not need to change */
{
    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 (!IsFIR)
    {
        // This function is called inside the ISR during SIR mode.
        if (IsListEmpty(&thisDev->rcvBufFree))
        {
            ListEntry = NULL;
        }
        else
        {
            ListEntry = RemoveHeadList(&thisDev->rcvBufFree);
        }
    }
    else
    {
        ListEntry = NDISSynchronizedRemoveHeadList(&thisDev->rcvBufFree,
                                                   &thisDev->interruptObj);
    }
    if (ListEntry)
    {
        rcvBuf = CONTAINING_RECORD(ListEntry,
                                   rcvBuffer,
                                   listEntry);
        if (IsFIR)
        {
            LOG_Data(thisDev, data);
        }
    }

    if (rcvBuf){

#ifdef DATALOGDEBUG
		{
			ULONG index;
			PUCHAR workPtr = data;

			RETAILMSG(1, (TEXT("IN\r\n")));
			for (index = 0; index < dataLen; index++)
			{
				RETAILMSG(1, (TEXT("  0x%x\r\n"), *workPtr++));
			}

⌨️ 快捷键说明

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